感觉每天都是匆匆忙忙的,每天似乎都是时间不够用一样,可是等真的想要动手敲代码的时候才发现,原来还有好多好多的知识点不是太熟练,所以,人不可以一直感觉自我良好, 有时间就是那种自我感觉良好的心态毁了自己的光明前途!

    今天我们真真正正的结束了iOS课程,但是这并不意味着结束,而是说有了新的开始,进入了新的阶段,所以努力与奋斗是丝毫不能减少的,我们将要面对的是更加严峻的考验,朋友们一起加油哦!

    下面我来为大笨蛋简单介绍下我们今天所讲的知识点吧。

    程序:代码编译过后, 形成的可执行文件(例如:*.app)

    进程:获取一个程序运行所需要的资源(例如:内存)

    线程:最小的执行单位,分配和调度资源

    注:一个进程至少有一个线程(主线程)

    那么什么为多线程呢顾名思义就是说效率高咱举一个例子, 就假如说程序是一个餐馆, 餐馆需要的资源(比如房子, 桌子等)由进程来获取, 线程相当于服务员, 是真正的执行者, 来分配资源(安排客户做那张餐桌,吃什么饭)等,多以多线程更加注重的应该是提高效率吧(个人理解哈)。

    下面我们来举一个例子吧:

    现在屏幕上放一个图片(UIImageview)和一个UIButton

self.view.backgroundColor = [UIColor yellowColor];

    self.iamgeView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"taiji"]];
_iamgeView.center = self.view.center;
[self.view addSubview:_iamgeView];
[_iamgeView release]; [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(begin) userInfo:nil repeats:YES]; UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(, , , );
[button setTitle:@"开始搬砖" forState:UIControlStateNormal];
[button addTarget:self action:@selector(moveBrick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];

    其中NSTimer关联的一个方法begin是让他开始旋转,还有上面所提到的UIimageView是个全局变量,因为在下面的时候还要用到,下面附上NSTimer和button所关联的方法

- (void)begin
{
[UIView beginAnimations:@"开始旋转" context:NULL]; //2D旋转
// _iamgeView.transform = CGAffineTransformRotate(self.iamgeView.transform, M_PI_4); //3D旋转
self.iamgeView.layer.transform = CATransform3DRotate(self.iamgeView.layer.transform, -M_PI_4, , , ); [UIView commitAnimations]; } - (void)moveBrick
{
//造成主线程阻塞
for (int i = ; i < ; i++) {
NSString *string = [NSString stringWithFormat:@"终于搬了%d快砖", i];
NSLog(@"%@", string);
}
}

    其中上面提到的begin方法一个是在二维平面上进行运动, 而另外一个则是在三维中运动,其中3D旋转中(-M_PI_4, 0, 0, 1) 参数的涵义分别为旋转角度,是否在x、y、z轴上旋转,其中如果想改变方向的话,只需要在旋转角度上面添加负号就OK了。但是这个有一种弊端,他会造成主线程阻塞,也就是说在执行搬砖的时候,主线程(图片的运动)会停止,直到搬砖结束为止。那么大家肯定会问,怎么才能实现同步运动呢,好,下面我就为大家讲解下一种做法,这种做法便是多线程方式,如有不理解可随时问我,代码中已有注释下面为大家插上代码

self.iamgeView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"taiji"]];
    _iamgeView.center = self.view.center;
    [self.view addSubview:_iamgeView];
    [_iamgeView release]; UIButton *proButton = [UIButton buttonWithType:UIButtonTypeSystem];
proButton.frame = CGRectMake(, , , );
[proButton setTitle:@"高级搬砖" forState:UIControlStateNormal];
[proButton addTarget:self action:@selector(moveBrickWithThread) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:proButton];

关联方法如下:

- (void)moveBrickWithThread
{
//多线程方式
//1.NSObject 后台执行
//自动帮你创建一个线程(子线程), 在后台执行代码
// [self performSelectorInBackground:@selector(moveBrickPro) withObject:nil]; //2.NSThread, 系统提供的线程类
//创建的子线程
// NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(moveBrickPro) object:nil];
// thread.name = @"码农1";
// [thread start];
// [thread release]; // [NSThread mainThread];
// NSLog(@"主线程:%@", [NSThread mainThread]);
// [NSThread currentThread];
// NSLog(@"当前线程:%@", [NSThread currentThread]); //3.NSOperationQueue, 操作队列, 自动创建一个线程, 操作队列中存放的是NSOperation(操作单元)
//栈:先进后出
//队列:先进先出 //NSOperation, 操作单元, 只能执行一次, 是抽象类 NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(moveBrickPro) object:nil];
//执行操作(只能够执行一次, 在主线程中执行)
// [invocation start];
// [invocation release];
__block RootViewController *blockSelf = self;
NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
[blockSelf moveBrickPro];
}]; //创建操作队列, 队列自带一个子线程
NSOperationQueue *quera = [[NSOperationQueue alloc] init];
//设置队列的最大并发数, 默认为-1, 表示并发数为无穷大
quera.maxConcurrentOperationCount = ;
//往队列里添加操作单元
[quera addOperation:invocation];
[quera addOperation:block];
[quera release];
[invocation release]; [NSThread mainThread];
NSLog(@"主对列:%@", [NSOperationQueue mainQueue]);
[NSThread currentThread];
NSLog(@"当前队列:%@", [NSOperationQueue currentQueue]); //把操作单元添加到 主队列 中, 操作单元在 主线程 中执行
//把操作单元添加到 子队列 中, 草错单元在 子线程 中执行 }
- (void)moveBrickPro
{
//主线程和子线程的区别
//1.主线程占用内存:1M, 子线程占用内存:512k
//2.子线程不会释放内存, 需要手动加自动释放池
//3.主线程中NSRunLoop自动开启, 子线程的NSRunLoop默认是关闭的, 不能够接受事件, 需要手动打开
//4.子线程中更新UI有可能会失败, 需要在主线程中更新UI
@autoreleasepool {
for (int i = ; i < ; i++) {
NSString *string = [NSString stringWithFormat:@"终于搬了%d快砖", i];
NSLog(@"%@", string);
}
//NSRunLoop, 每一个线程都有一个NSRunLoop, 来监控和接受事件
//开启子线程的事件循环
[[NSRunLoop currentRunLoop] run]; [self performSelectorOnMainThread:@selector(refreshUI) withObject:nil waitUntilDone:YES];
}
[NSThread mainThread];
NSLog(@"主线程:%@", [NSThread mainThread]);
[NSThread currentThread];
NSLog(@"当前线程:%@", [NSThread currentThread]); }

    ⭐️⭐️⭐️接下来就是今天的最后一个知识点了那便是多线程 的终极版了 这次我们来通过一个现实生活中的例子来让大家对多线程的了解更加深刻吧,想必大家都知道车站售票吧,如果只有一个窗口,那车站还不等爆了,所以这就类似于我们的多线程,引入多个子线程来进行管理,首先前两部还是一样的在跟试图控制器上添加一个按钮UIButton和图片然后让button关联方法,具体方法如下(重中之重)

//开始卖票
- (void)startSale
{
currentTicket = ;
saleCount = ;
//创建售票窗口
NSThread *windowOne = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
windowOne.name = @"A01"; NSThread *windowTwo = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
windowTwo.name = @"B02"; //开始售票
[windowOne start];
[windowOne release];
[windowTwo start];
[windowTwo release];
} - (void)saleTicket
{
//多线程可以提高执行效果, 相反的带来的是, 开销大喝资源的抢夺
while (YES) {
[NSThread sleepForTimeInterval:0.2];
//加锁
// [_lock lock];
if (currentTicket > ) {
currentTicket--;
saleCount++;
NSLog(@"窗口:%@, 卖了第%d张 剩余%d张", [[NSThread currentThread] name], saleCount, currentTicket);
} else {
NSLog(@"票已售空");
break;
}
// [_lock unlock];
}
}

    大家看到了我注释掉得两句话了把[_lock lock],[_lock unlock],首先既然是售票,总得知道总共有多少张票,和已售多少吧,所以呢,在我们先开始时间我们先要初始化两个全局变量,并赋值,这里我赋的总票数为100,已售为0。这样就算是基本完成了, 但是千万不要大意,刚才那两句话如果不加上的画,执行顺序就会出错,下面给大家看个例子:

    这就是部分效果, 大家会发现完全发生了紊乱,更甚至票都为负数了还在继续卖,所以那两句话一定要加上,当一个窗口开始卖票时将此票短暂占为己有,等售出后再打开,也就是说不让他们互相抢夺资源,下面的是加上那两句话后的效果。

    注:但是如果要加上那两句话的话,就必须要初始化个NSLock并且一定要记得释放,但是他的释放和其他的不一样,要格外的谨慎,稍不留神,程序就会崩溃,所以应该写到dealloc里面最为安全。

    通过对比大家肯定会发现这个明显很有顺序,没有你争我夺的那种架势,所以朋友们,那两句话一定要加上哦,保护资源。

    今天下课时间我还还对GCD做了一个小小的了解,等明天了我再好好钻研下再给友友们分享哈,今天就先到这里了,下周就要开始新的项目了,好紧张有木有,不过还是安奈不住心中那小小的激动啊,加油,come on!

 

iOS多线程及其感悟的更多相关文章

  1. iOS多线程主题

    下面是:2个并发进程.和2个并发线程的示意图: 下面介绍三种多线程技术(Thread.Cocoa Operation.Grand Central Dispatch): 1.最轻量级Thread(需要自 ...

  2. iOS多线程技术方案

    iOS多线程技术方案 目录 一.多线程简介 1.多线程的由来 2.耗时操作的模拟试验 3.进程和线程 4.多线程的概念及原理 5.多线程的优缺点和一个Tip 6.主线程 7.技术方案 二.Pthrea ...

  3. iOS 多线程GCD的基本使用

    <iOS多线程简介>中提到:GCD中有2个核心概念:1.任务(执行什么操作)2.队列(用来存放任务) 那么多线程GCD的基本使用有哪些呢? 可以分以下多种情况: 1.异步函数 + 并发队列 ...

  4. iOS多线程到底不安全在哪里?

    iOS多线程安全的概念在很多地方都会遇到,为什么不安全,不安全又该怎么去定义,其实是个值得深究的话题. 共享状态,多线程共同访问某个对象的property,在iOS编程里是很普遍的使用场景,我们就从P ...

  5. iOS多线程的详情使用示例--简进祥

    大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能 ...

  6. iOS多线程

    关于iOS多线程 概述 这篇文章中,我不会说多线程是什么.线程和进程的区别.多线程有什么用,当然我也不会说什么是串行.什么是并行等问题,这些我们应该都知道的. 在 iOS 中其实目前有 4 套多线程方 ...

  7. iOS多线程学习及总结

    能有份网上的存储资料,备以后提升及参考 iOS 多线程编程 简介 一.      iOS有三种多线程编程的技术,分别是: 1.        NSThread 2.        Cocoa NSOp ...

  8. iOS多线程杂论

    iOS多线程的分布 (1) NSThread (2) NSOperation (3) GCD 现在对下面三个进行一个个的分析,希望那里说得不对的地方希望简友们帮我指点一二. 1,NSThread 优点 ...

  9. iOS多线程开发

    概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...

随机推荐

  1. 返回ipv 地址

    //返回ipv 地址 public static string GetIP4Address() { string IP4Address = String.Empty; foreach (IPAddre ...

  2. Android-隐式Intent

    隐式Intent表示不具体明确要打开的activity,利用隐式intent我们可以打开其他应用. 一个隐式intent的主要组成部分: 1.action 要执行的操作. 通常以intent类的常量表 ...

  3. Windows下使用ODBC API访问数据库之关键

    本文采用SQL2005 + VS2008环境,以ODBC API方式成功连接数据库. 1.SQL安装和环境配置 这部分网上随便搜一下都有很多资料,而且很容易就可以配置成功. 注意的关键点: SA账号配 ...

  4. Xcode快捷键 ---- 提高效率

    Mac中主要有四个修饰键,分别是Command,Control,Option和Shift.     1. ⌘ + L 搜索行数,输入行数,调到指定行数   2.⌘ + shift + O 查询flie ...

  5. 访问MySQL数据库时,报“找不到请求的 .net Framework 数据提供程序。可能没有安装。”的解决方案

    最近开发了一个系统,在测试环境上进行部署(win7环境)并测试,没有发现问题:但是把系统部署到win Server2008R2上之后,部分页面就报“找不到请求的 .net Framework 数据提供 ...

  6. 1、Spark 通过api,hfile两种形式获取hbase数据,简单样例

    pom内容: <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-se ...

  7. 6 log4j -- 一个笨的使用方法

    log4j的说明: Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件,甚至是套接口服务器.NT的事件记录器.UNIX Syslog ...

  8. Spring dbcp连接池简单配置 示例

    一.配置db.properties属性文件 #database connection config connection.username=sa connection.password=sa conn ...

  9. hadoop之MapReduce WordCount分析

    MapReduce的设计思想 主要的思想是分而治之(divide and conquer),分治算法. 将一个大的问题切分成很多小的问题,然后在集群中的各个节点上执行,这既是Map过程.在Map过程结 ...

  10. php如何返回一个image文件

    The important points is that you must send a Content-Type header. Also, you must be careful not incl ...