iOS -- Dispatch Group 机制(27)
通过 Dispatch Group 机制,根据系统资源状况来执行任务
dispatch group 是 GCD 的一项特性,能够把任务分组,调用者可以等待这组任务执行完毕,也可以在提供回调函数之后继续往下执行, 这组任务完成时, 调用者会得到通知, 这个功能最重要的用途是 将要并发执行的多个任务合为一组, 于是调用者就可以知道这些任务何时才能全部执行完毕, 比方说,可以把压缩一系列文件的任务表示成 dispatch group
下面的这个函数可以创建 dispatch group
dispatch_group_t group = dispatch_group_create();
dispatch group 就是个简单的数据结构, 这种结构彼此之间没有什么区别, 它不像派发队列,后者还有一个用来区别身份的标识符,想把任务编组, 有两种办法, 第一种是用下面的方法:
void dispatch_group_asyns(dispatch_group_t group,
dispatch_queue_t queue
dispatch_block_t block);
它是普通 dispatch_async 函数的变体, 比原来多一个参数, 用于表示待执行的块所属的组, 还有中办法能指定任务所属的 dispatch group
void dispatch_group_enter(dispatch_group_t);
void dispatch_group_leave(dispatch_group_t);
前者能够使分组里正要执行的任务数递增,而后者则使之递减, 由此可知, 调用了 dispatch_group_enter 以后, 必须有与之对应的 dispatch_group_leave 才行, 这与引用计数相似,在使用 dispatch group 时, 如果调用了 enter 之后,没有相应的 leave 操作, 那么这一组任务就永远执行不完.
下面这个函数可用于等待 dispatch group 执行完毕.
long dispatch_group_wait(dispatch_group_t group,
dispatch_time_t timeout);
此函数接受两个参数, 一个是要等待的 group, 另一个是代表等待时间的 timeout 值. timeout 参数表示函数在等待 dispatch group执行完毕时, 应该阻塞多久, 如果执行 dispatch group 所需的时间小于 timeout ,则返回 0, 否则返回 非 0 值. 此参数也可以取常量 DISPATCH_TIME_FOREVER, 这表示函数会一直等待 dispatch group 执行完毕, 而不会超时.
除了可以用上面那个函数等待 dispatch group 执行完毕之外, 也可以换个办法, 使用下列函数.
void dispatch_group_notify(dispatch_group_t group
dispatch_queue_t queue
dispatch_block_t block);
与 wait 函数略有不同的是: 开发者可以向此函数传入块, 等 dispatch group 执行完毕之后, 块会在特定的线程上执行, 一般都在主线程执行.
如果想令数组中的每个对象都执行某项任务, 并且想等待所有文物执行完毕, 那么就可以用这个 GCD 特性来实现:
dispatch_quwuw_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIOROTY_DEFAULT, 0);
dispatch_group_t dispatchGroup = dispatch_group_creat();
for (id object in array){
dispatch_group_async(dispatchGroup, queue, ^{
[object work];
});
dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER);
// 完成任务后继续处理
}
若当前线程不应该阻塞, 则可用 notify 函数来取代 wait:
dispatch_queue_t notifyQueue = dispatch_get_main_queue();
dispatch_group_nitify(dispatchGroup, notifyQueue, ^{
// 完成任务后继续处理
});
总结:
一系列任务可归于一个 dispatch group 之中, 开发者可以在这组任务执行完毕时获得通知.
通过 dispatch group ,可以在并发式派发队列里面同时执行多项任务, 此时,GCD 会根据系统资源状况来调度这些并发执行的任务.