标签:
https://github.com/xufeng79x/GCDDemo
1.简介
在前面的两篇博文中我介绍了GCD的一般使用方法和死锁的分析调查。本博文中继续讲解GCD的其他比较常用的几个使用方法。
2.线程间的通信
线程间通信意指如何在当前线程中去通知或者去调度其他线程完成任务。
比较经典的一个用例为将耗时操作放在某个线程中(非主队列任务)然后完成后去更新控件(主队列任务)。
-(void)loadImage { dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 1. 网络上图片的URL NSURL *url = [NSURL URLWithString:@"http://att2.citysbs.com/hangzhou/image1/2010/06/28-14/middle_20100628_479774d896cf207fed251P3nfB3V8Pmp.jpg"]; // 2. 获取网络图片数据,二进制 NSData *data = [NSData dataWithContentsOfURL:url]; // 3. 二进制数据转换成图片 UIImage *image = [UIImage imageWithData:data]; // 4.通知主线程更新UI dispatch_async(dispatch_get_main_queue(), ^{ self.image.image = image; }); }); }
如果你自己测试代码测试那么需要在工程的info.plist中进行如下设定,增加如下选项:
3.延迟执行
-(void) delayExecute { // 延迟时间 dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)); NSLog(@"start at %@", [NSDate new]); // 指定队列,延迟指定时间后执行任务 dispatch_after(when, dispatch_get_global_queue(0, 0), ^{ NSLog(@"end at %@", [NSDate new]); NSLog(@"%@", [NSThread currentThread]); }); }
结果:
2016-01-18 23:43:29.279 GCDDemo[900:20322] start at 2016-01-18 15:43:29 +0000 2016-01-18 23:43:39.278 GCDDemo[900:20386] end at 2016-01-18 15:43:39 +0000 2016-01-18 23:43:39.278 GCDDemo[900:20386] <NSThread: 0x78f23820>{number = 2, name = (null)}
4.调度组
调度组的应用场景:
开发的时候有的时候出现多个网络请求,在多个网络请求全部结束后统一去触发某个处理(更新UI通知用户等)。
比如下载多部小说后通知用户小说已经全部下载完毕了。
基本步骤如下:
-(void) group { // 实例化一个调度组 dispatch_group_t group = dispatch_group_create(); // 创建或者获取队列 dispatch_queue_t queue1 = dispatch_get_global_queue(0, 0); // 将任务放入队列,包进到指定group dispatch_group_async(group, queue1, ^{ NSLog(@"下载小说A----%@", [NSThread currentThread]); }); // 创建或者获取队列 dispatch_queue_t queue2 = dispatch_queue_create("xf", DISPATCH_QUEUE_CONCURRENT); dispatch_group_async(group, queue2, ^{ NSLog(@"下载小说B----%@", [NSThread currentThread]); }); // 创建或者获取队列 dispatch_queue_t queue3 = dispatch_queue_create("xf", DISPATCH_QUEUE_SERIAL); dispatch_group_async(group, queue3, ^{ NSLog(@"下载小说C----%@", [NSThread currentThread]); }); // 创建或者获取队列 dispatch_queue_t queue4 = dispatch_get_main_queue(); dispatch_group_notify(group, queue4, ^{ NSLog(@"下载完成,请观看----%@", [NSThread currentThread]); }); }
结果:
2016-01-19 00:08:44.982 GCDDemo[1163:27306] 下载小说B----<NSThread: 0x7b78d190>{number = 4, name = (null)} 2016-01-19 00:08:44.982 GCDDemo[1163:27312] 下载小说A----<NSThread: 0x7b789700>{number = 3, name = (null)} 2016-01-19 00:08:44.982 GCDDemo[1163:27305] 下载小说C----<NSThread: 0x7cc7a9a0>{number = 2, name = (null)} 2016-01-19 00:08:44.983 GCDDemo[1163:27254] 下载完成,请观看----<NSThread: 0x7c872a50>{number = 1, name = main}
总结:
可以看到,放入group的任务可以在不同的队列中,group能够统一的感知到所有任务是否全部完成。
5.一次性执行
-(void)once { static dispatch_once_t onceToken; NSLog(@"out onceToken is %ld", onceToken); dispatch_once(&onceToken, ^{ NSLog(@"in onceToken is %ld", onceToken); NSLog(@"执行了一次!"); }); NSLog(@"完成"); }
结果:
2016-01-19 00:29:47.223 GCDDemo[1700:42886] out onceToken is 0 2016-01-19 00:29:47.224 GCDDemo[1700:42886] in onceToken is -1074347968 2016-01-19 00:29:47.224 GCDDemo[1700:42886] 执行了一次! 2016-01-19 00:29:47.224 GCDDemo[1700:42886] 完成 2016-01-19 00:29:49.517 GCDDemo[1700:42886] out onceToken is -1 2016-01-19 00:29:49.517 GCDDemo[1700:42886] 完成 2016-01-19 00:29:52.806 GCDDemo[1700:42886] out onceToken is -1 2016-01-19 00:29:52.807 GCDDemo[1700:42886] 完成
总结:
即使我们多次点击屏幕,“执行一次!”这段log也只会出书一次,换句话说,任务只被执行一次。
其实这段代码是通过onceToken这个静态数据来判断任务是否已经被执行了,当判断为-1时候认为任务已经被执行了。
如果我们一开始就初始化onceToken为-1,其实程序就一次也不会做任务了。不信试一试。
场景:
我们可以将这个特性应用于单例的创建。
标签:
原文地址:http://www.cnblogs.com/ios123/p/5140190.html