dispatch group是GCD的一项特性,能够把任务分组。调用者可以等待这组任务执行完毕,也可以在提供回调函数之后继续往下执行,这组任务完成时,调用者会得到通知。
如果想令某容器中的每个对象都执行某项任务,并且等待所有任务执行完毕,那么就可以使用这个GCD特性来实现:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 创建dispatch group
dispatch_group_t group = dispatch_group_create();
for (id object in colletion){
// 派发任务
dispatch_group_async(group, queue, ^{
[object performTask];
});
}
// 参数1:要等待的group,参数2:等待时间值,表示函数在等待group执行完毕时,应该阻塞多久
// 等待组内任务执行完毕,会阻塞当前线程,等所有任务执行完毕后,再继续向下执行
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
假如当前线程不应阻塞,又想在这组任务全部完成后收到消息,可用notify函数来替代wait:
// notify回调时所选用的队列可以根据情况来定,这里用的是主队列
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 完成任务后继续接下来的操作
});
把某些任务放在优先级高的线程上执行,同时所有任务仍然属于一个group:
// 创建两个优先级不同的队列
dispatch_queue_t lowPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_queue_t HighPriorityQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
// 创建dispatch group
dispatch_group_t group = dispatch_group_create();
for (id object in lowPriorityColletion){
dispatch_group_async(group, lowPriorityQueue, ^{
[object performTask];
});
}
for (id object in HighPriorityColletion){
dispatch_group_async(group, HighPriorityQueue, ^{
[object performTask];
});
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 完成任务后继续接下来的操作
});
通过dispatch group,可以在并发式派发队列里同时执行多项任务,此时GCD会根据系统资源状况来调度这些并发执行的任务,开发者若自己实现此功能,则需要编写大量代码。
dispatch_apply在串行队列中等同于for循环:
dispatch_queue_t queue = dispatch_queue_create("com.effectiveobjectivec.queue", NULL);
dispatch_apply(10, queue, ^(size_t i) {
NSLog(@"i : %ld",i);
});
dispatch_apply在并发队列,系统就根据系统资源状况来并行执行这些块:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(300, queue, ^(size_t i) {
[self performApply:i];
});
使用apply函数会持续阻塞,直到所有任务都执行完毕为止。
由此可见,假如把块派给了当前队列(或者体系中高于当前队列的串行队列),就将导致死锁。若想在后台执行任务,则应使用dispatch group。
网友评论