iOS多线程
2016-03-07 14:28
357 查看
iOS中多线程实现方案:
1.NSThread
1个NSThread对象就代表一条线程
创建线程:
启动线程:
2 GCD(Grand Central Dispatch)
1)为多核的并行运算提出解决方案。
2)会自动管理线程的生命周期(创建线程,调度线程,销毁线程)。
3)只需要告诉GCD想要执行什么任务,不需要编写任何线程管理的代码。
步骤:
1)定制任务
2)将任务放到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行。FIFO原则
GCD中有2个用来执行任务的函数:
1)同步方式(只能在当前的线路中执行任务,不具备开启新线程的能力)
2)异步方式(可以在新的线路中执行任务,具备开启新线程的能力)
GCD队列分为两大类:
1)并发队列(Concurrent Dispatch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
只有在异步方式“dispatch_async”下才有效。
2)串行队列(Serial Dispathc Queue)
让任务一个接一个的执行
注意:使用sync向当前串行队列中添加任务,会卡住当前的串行队列。
因为当前任务或者方法已经在主队列中,在同步(sync)方式下,仍往该队列中添加任务,那么势必等当前方法执行完之后,才能执行新添加的任务,而新添加的任务不执行,当前方法也不会往下继续执行完。所以会卡住。
2.1 GCD进程间通讯:
2.2 利用GCD执行延迟操作:
不会卡住dispatch_after之后的操作,仍继续往下执行,等时间到了再回头执行里面的操作
2.3 利用GCD控制代码执行的次数
2.4 将读取/写入操作放到一个新建的串行队列中同步执行,可以代替同步锁,保证数据同步。
由于多个getter方法可以并发执行,而getter方法与setter方法间不能并发执行,利用这个特点,可以将读取和写入操作都放到一个“全局并发队列中”。
但是,为了保证并发队列中的读取/写入操作不是随时执行的,可以利用GCD的“barrier”功能。
在队列中,栅栏块必须单独执行,不能与其他块并行
3.NSOperation
NSOperation和NSOperationQueue实现多线程的步骤
1)先将需要执行的操作封装到一个NSOperation对象中
2)然后将NSOperation对象添加到NSOperationQueue中
3)系统会自动将NSOperationQueue中的NSOperation取出来
4)将取出的NSOperation封装的操作放到一条新线程中执行
3.1设置最大并发数
3.2操作依赖关系
NSOperation之间可以设置依赖来保证执行次序
如:一定要当操作A完成之后才可以执行B操作
3.3取消队列的所有操作
3.4暂停/恢复
使用NSOperation及NSOperationQueue的好处:
1)便于取消操作。在任务运
9cb2
行之前,可以在NSOperation对象上调用cancel方法,该方法会设置对象内的标志位,表明此任务不需要执行。
2)指定操作间的依赖关系。使特定的操作必须在另外一个操作顺利执行完后执行。
3)通过KVO监控NSOperation对象的属性,可以在某个任务变更其状态时得到通知。
1.NSThread
1个NSThread对象就代表一条线程
创建线程:
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
启动线程:
[thread1 start];
2 GCD(Grand Central Dispatch)
1)为多核的并行运算提出解决方案。
2)会自动管理线程的生命周期(创建线程,调度线程,销毁线程)。
3)只需要告诉GCD想要执行什么任务,不需要编写任何线程管理的代码。
步骤:
1)定制任务
2)将任务放到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行。FIFO原则
GCD中有2个用来执行任务的函数:
1)同步方式(只能在当前的线路中执行任务,不具备开启新线程的能力)
dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>);
2)异步方式(可以在新的线路中执行任务,具备开启新线程的能力)
dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>);
GCD队列分为两大类:
1)并发队列(Concurrent Dispatch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
只有在异步方式“dispatch_async”下才有效。
2)串行队列(Serial Dispathc Queue)
让任务一个接一个的执行
// 1.获得全局的并发队列: dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 并发队列可选择的优先级: #define DISPATCH_QUEUE_PRIORITY_HIGH 2 #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 #define DISPATCH_QUEUE_PRIORITY_LOW (-2) #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
// 2.将任务加到队列中,异步方式执行(可创建子线程) dispatch_async(queue, ^{ // 执行的任务 });
// 创建串行队列 dispatch_queue_t queue2 = dispatch_queue_create("name", NULL); // 非ARC需要手动释放 dispatch_release(queue2);
// 获得主队列 dispatch_queue_t mainQueue = dispatch_get_main_queue();
注意:使用sync向当前串行队列中添加任务,会卡住当前的串行队列。
因为当前任务或者方法已经在主队列中,在同步(sync)方式下,仍往该队列中添加任务,那么势必等当前方法执行完之后,才能执行新添加的任务,而新添加的任务不执行,当前方法也不会往下继续执行完。所以会卡住。
2.1 GCD进程间通讯:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 子线程执行一些比较耗时的操作 // ... dispatch_async(dispatch_get_main_queue(), ^{ // 回到主线程,执行一些UI相关的操作 // ... }); });
2.2 利用GCD执行延迟操作:
不会卡住dispatch_after之后的操作,仍继续往下执行,等时间到了再回头执行里面的操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 操作... });
2.3 利用GCD控制代码执行的次数
static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 只执行一次的操作 // ... });
2.4 将读取/写入操作放到一个新建的串行队列中同步执行,可以代替同步锁,保证数据同步。
由于多个getter方法可以并发执行,而getter方法与setter方法间不能并发执行,利用这个特点,可以将读取和写入操作都放到一个“全局并发队列中”。
但是,为了保证并发队列中的读取/写入操作不是随时执行的,可以利用GCD的“barrier”功能。
在队列中,栅栏块必须单独执行,不能与其他块并行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 虽然是并发队列,但“栅栏块”中的操作必须单独执行 dispatch_barrier_sync(queue, ^{ // 写入操作... });
3.NSOperation
NSOperation和NSOperationQueue实现多线程的步骤
1)先将需要执行的操作封装到一个NSOperation对象中
2)然后将NSOperation对象添加到NSOperationQueue中
3)系统会自动将NSOperationQueue中的NSOperation取出来
4)将取出的NSOperation封装的操作放到一条新线程中执行
// 1.将操作封装到NSOperation对象中 NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ // 执行的操作... }]; [operation1 addExecutionBlock:^{ // 执行完任务1后要执行的操作 }]; // 2.创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // NSOperationQueue *queue2 = [NSOperationQueue mainQueue];(主队列) // 3.添加操作到队列中 [queue addOperation:operation1];
3.1设置最大并发数
queue.maxConcurrentOperationCount = 2;
3.2操作依赖关系
NSOperation之间可以设置依赖来保证执行次序
如:一定要当操作A完成之后才可以执行B操作
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{ // A执行的操作... }]; NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{ // B执行的操作... }]; // 操作B依赖于操作A [operationB addDependency:operationA];
3.3取消队列的所有操作
[queue cancelAllOperations];
3.4暂停/恢复
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { // 开始拖拽时暂停/恢复操作 [queue setSuspended:YES]; // or NO }
使用NSOperation及NSOperationQueue的好处:
1)便于取消操作。在任务运
9cb2
行之前,可以在NSOperation对象上调用cancel方法,该方法会设置对象内的标志位,表明此任务不需要执行。
2)指定操作间的依赖关系。使特定的操作必须在另外一个操作顺利执行完后执行。
3)通过KVO监控NSOperation对象的属性,可以在某个任务变更其状态时得到通知。
相关文章推荐
- 【Xamarin挖墙脚系列:Xamarin.IOS的程序的结构】
- IOS中对Url进行编码和解码
- 【Xamarin 挖墙脚系列:IOS 开发界面的3种方式】
- ios googlemaps 开发 设置地图可见所有大头针
- iOS打包,证书配置等
- IOS常用第三方库
- iphone ios 和pc间通过wifi通讯,连接
- iOS项目统计代码行数
- iOS 预编译命令小记
- 翻翻git之---偏向iOS风格的Switch ToggleSwitch
- 翻翻git之---偏向iOS风格的Switch ToggleSwitch
- Xamarin IOS – hello word
- IOS Document文档
- iOS 核心动画 书籍
- iOS小demo之画虚线
- iOS小demo之获取键盘高度
- IOS自带处理缓存方法
- iOS开发之使用lipo命令制作模拟器与真机通用静态库
- iOS rootViewController侧滑返回卡住的解决方法
- iOS开发Debug之20像素的空白