GCD(二)
来源:互联网 发布:网络链接不上 编辑:程序博客网 时间:2024/05/17 04:06
在开发中,我们经常会碰到一类问题,A任务开始执行的前提是B任务执行完成了,针对这种,如果只是简简单单的一个任务接一个任务,可能使用block 嵌套也可以做到,但是如果是C任务开始执行需要等A、B两个异步任务完成,这个呢?这里就需要使用到一些GCD的高级用法。
1、gcd的分组
//创建分组 dispatch_group_t group = dispatch_group_create(); //创建队列 dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT); //往分组中添加任务 dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:2];//模拟耗时操作 NSLog(@"11111 %@", [NSThread currentThread]); }); //往分组中添加任务 dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:1];//模拟耗时操作 NSLog(@"2222 %@", [NSThread currentThread]); }); //分组中任务完成以后 通知该block 执行 dispatch_group_notify(group, queue, ^{ NSLog(@"完成 %@", [NSThread currentThread]); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"通知主线程刷新UI %@", [NSThread currentThread]); }); });
执行结果
2017-09-15 11:33:40.426 iOSTest[34497:828682] 2222 <NSThread: 0x600000260080>{number = 3, name = (null)}2017-09-15 11:33:41.426 iOSTest[34497:828660] 11111 <NSThread: 0x608000261d80>{number = 4, name = (null)}2017-09-15 11:33:41.427 iOSTest[34497:828660] 完成 <NSThread: 0x608000261d80>{number = 4, name = (null)}2017-09-15 11:33:41.427 iOSTest[34497:828365] 通知主线程刷新UI <NSThread: 0x60800007b980>{number = 1, name = main}
根据执行结果,可知,使用group可以实现多任务之间的依赖关系,这是直接往group中添加任务,但是有时候,我们的任务一层一层的嵌套了多层Block,这个时候,代码如下:
//创建分组 dispatch_group_t group = dispatch_group_create(); //创建队列 dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT); //往分组中添加任务 dispatch_group_async(group, queue, ^{ void (^task)(void) = ^{ [NSThread sleepForTimeInterval:2];//模拟耗时操作 NSLog(@"11111 %@", [NSThread currentThread]); }; dispatch_async(dispatch_get_global_queue(0, 0), task); NSLog(@"11111---- %@", [NSThread currentThread]); }); //往分组中添加任务 dispatch_group_async(group, queue, ^{ void (^task)(void) = ^ { [NSThread sleepForTimeInterval:1];//模拟耗时操作 NSLog(@"2222 %@", [NSThread currentThread]); }; dispatch_async(dispatch_get_global_queue(0, 0), task); NSLog(@"2222------- %@", [NSThread currentThread]); }); //分组中任务完成以后 通知该block 执行 dispatch_group_notify(group, queue, ^{ NSLog(@"完成 %@", [NSThread currentThread]); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"通知主线程刷新UI %@", [NSThread currentThread]); }); });
执行结果:
2017-09-15 11:44:06.447 iOSTest[34981:881063] 2222------- <NSThread: 0x610000068000>{number = 4, name = (null)}2017-09-15 11:44:06.447 iOSTest[34981:881046] 11111---- <NSThread: 0x600000071f40>{number = 3, name = (null)}2017-09-15 11:44:06.448 iOSTest[34981:881046] 完成 <NSThread: 0x600000071f40>{number = 3, name = (null)}2017-09-15 11:44:06.450 iOSTest[34981:880987] 通知主线程刷新UI <NSThread: 0x60000006c340>{number = 1, name = main}2017-09-15 11:44:07.450 iOSTest[34981:881064] 2222 <NSThread: 0x6000000708c0>{number = 5, name = (null)}2017-09-15 11:44:08.452 iOSTest[34981:881049] 11111 <NSThread: 0x61000006d5c0>{number = 6, name = (null)}
根据结果我们可以知道,其实刷新主线程的时候,其他两个任务中并没有真正的完成,因为另外两个任务中嵌套了子任务,你就会发现这样执行任务还是不能满足需求,那要怎么做呢?其实group提供了dispatch_group_enter()与dispatch_group_leave()方法来自己组合,但是一定要注意,这两个方法一定需要成对使用,否则会引起莫名Bug。代码如下:
//创建分组 dispatch_group_t group = dispatch_group_create(); //创建队列 dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT); //往分组中添加任务 dispatch_group_enter(group); dispatch_async(queue, ^{ void (^task)(void) = ^{ [NSThread sleepForTimeInterval:2];//模拟耗时操作 NSLog(@"11111 %@", [NSThread currentThread]); dispatch_group_leave(group); }; dispatch_async(dispatch_get_global_queue(0, 0), task); NSLog(@"11111---- %@", [NSThread currentThread]); }); //往分组中添加任务 dispatch_group_enter(group); dispatch_async(queue, ^{ void (^task)(void) = ^ { [NSThread sleepForTimeInterval:1];//模拟耗时操作 NSLog(@"2222 %@", [NSThread currentThread]); dispatch_group_leave(group); }; dispatch_async(dispatch_get_global_queue(0, 0), task); NSLog(@"2222------- %@", [NSThread currentThread]); }); //分组中任务完成以后 通知该block 执行 dispatch_group_notify(group, queue, ^{ NSLog(@"完成 %@", [NSThread currentThread]); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"通知主线程刷新UI %@", [NSThread currentThread]); }); });
执行结果如下:
2017-09-15 11:48:05.641 iOSTest[35128:902591] 11111---- <NSThread: 0x610000073d40>{number = 3, name = (null)}2017-09-15 11:48:05.641 iOSTest[35128:902608] 2222------- <NSThread: 0x60800006fd00>{number = 4, name = (null)}2017-09-15 11:48:06.644 iOSTest[35128:902609] 2222 <NSThread: 0x60000006cb00>{number = 5, name = (null)}2017-09-15 11:48:07.644 iOSTest[35128:902593] 11111 <NSThread: 0x6080000721c0>{number = 6, name = (null)}2017-09-15 11:48:07.644 iOSTest[35128:902593] 完成 <NSThread: 0x6080000721c0>{number = 6, name = (null)}2017-09-15 11:48:07.645 iOSTest[35128:902524] 通知主线程刷新UI <NSThread: 0x61000006e280>{number = 1, name = main}
可以看出,我们想要的结果又回来了。但是这里有个比较重要的地方要注意,这个enter不要放到任务里面了,因为任务是异步执行的,可能会执行执行了下面的完成以后,才执行上面的任务了。
阅读全文
0 0
- GCD(二)
- GCD(二)
- GCD 多线程 (二)
- GCD 多线程 (二)
- IOS GCD 使用 (二)
- GCD之二:dispatch_queue_create
- iOS--GCD(二)
- swift之GCD(二)
- GCD 深入理解二
- GCD理解(二)
- 多线程(二) GCD
- 使用GCD(二)
- GCD入门介绍二
- 多线程GCD(二)
- GCD 整理(二)
- gcd学习理解(二)
- iOS GCD(二)
- gcd 学习总结 (二)
- PAT A1024. Palindromic Number (25)
- multi-class logestic regression的python实现
- 看完这,再也不用为项目报告发愁了
- 基于redis的setnx()、get()、getset()方法 分布式锁
- 3分钟通过一个App的演示深入理解区块链运行原理
- GCD(二)
- Netty5的客户端
- Nmap扫描漏洞
- angularJS简介和几个重要的例子
- Hive 的基本使用
- 用JS+div在页面指定位置写一个电子时钟
- JS运行题常见变量和作用域
- 比特币钱包BitPay使用教程
- mysql乐观锁总结和实践