问题的产生
在开发过程中有时会遇到这样的需求:并发执行一组任务,任务全部结束后,对执行结果进行某些操作。
比如类似下面这样。
1 | for (id obj in array) { |
直接使用以上代码会导致阻塞,等待任务组全部都执行完才执行 doSomethingWithArray: 。
简单地加入 dispatch_async 也是不行的,这样 doSomethingWithArray: 不能在正确的时机运行。
不使用 dispatch_group 的解决方案
在知道 dispatch_group 之前 ,我的解决方法是加入一个原子计数器,等所有任务都执行完了,再执行结果列表的操作。
1 | __block volatile int32_t remainCount = (int32_t)array.count; |
使用 dispatch_group 的解决方案
可以看到,上面的方法不太优雅。事实上,Apple 为我们准备了专门用来处理这种问题的 dispatch_group。
一个 dispatch group 可以用来将多个 block 组成一组以监测这些 block 全部完成或者等待全部完成时发出的消息。所以我们现在可以重写代码:
1 | dispatch_queue_t queue = dispatch_get_global_qeueue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); |
在不能使用 dispatch_group_async 的情况下,使用 dispatch_group_enter/dispatch_group_leave。
1 | dispatch_queue_t queue = dispatch_get_global_qeueue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); |
dispatch_group 相关方法
dispatch_group_create
创建一个调度任务组dispatch_group_async
把一个任务异步提交到任务组里dispatch_group_enter/dispatch_group_leave
这两个方法显示的讲任务组中的任务未执行完毕的任务数目加减1,这种方式用在不使用 dispatch_group_async 提交任务的情况下。注意:这两个函数要配合使用,有 enter 要有 leave,这样才能保证功能完整实现。也可以用这对函数来让一个闭包关联多个 groupdispatch_group_notify
用来监听任务组事件的执行完毕dispatch_group_wait
设置等待时间,在等待时间结束后,如果还没有执行完任务组,则返回。返回0代表执行成功,非0则执行失败