一、背景简介
平时在进行多线程处理任务时,有时候希望多个任务之间存在着一种联系,希望在所有的任务执行完后做一些总结性处理。
那么就可以将多个任务放在一个任务组中进行统一管理。dispatch提供了相应的API供我们完成这一需求。

二、dispatch_group_t相关属性介绍
1.dispatch_group_async(group, queue, block);
将block任务添加到queue队列,并被group组管理
2.dispatch_group_enter(group);
声明dispatch_group_enter(group)下面的任务由group组管理,group组的任务数+1
3.dispatch_group_leave(group);
相应的任务执行完成,group组的任务数-1
4.dispatch_group_create();
创建一个group组
5.dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
当前线程暂停,等待dispatch_group_wait(group1, DISPATCH_TIME_FOREVER)上面的任务执行完成后,线程才继续执行。
6.dispatch_group_notify(group1, queue1,block);
监听group组中任务的完成状态,当所有的任务都执行完成后,触发block块,执行总结性处理。

三、常见用法的区别
在使用group组处理任务时,常见的有两种组合。
其一:

dispatch_group_async(group, queue, block);

dispatch_group_notify(group1, queue1, block);

在这种组合下,根据任务是同步、异步又分为两种,这两种组合的执行代码与运行结果如下:

第一种:同步任务时

  dispatch_queue_t queue1 = dispatch_queue_create("dispatchGroupMethod1.queue1", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group1 = dispatch_group_create(); dispatch_group_async(group1, queue1, ^{
dispatch_sync(queue1, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-同步任务执行-:%ld",@"任务1",(long)i); }
});
}); dispatch_group_async(group1, queue1, ^{
dispatch_sync(queue1, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-同步任务执行-:%ld",@"任务2",(long)i); }
});
}); // //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
// dispatch_group_wait(group1, DISPATCH_TIME_FOREVER); //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
dispatch_group_notify(group1, queue1, ^{
NSLog(@"Method1-全部任务执行完成");
});

同步任务运行结果:

-- ::05.883 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::05.884 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::06.885 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::06.885 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::07.886 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::07.886 MyTestWorkProduct[:] 任务1-同步任务执行-:
-- ::07.886 MyTestWorkProduct[:] Method1-全部任务执行完成

第二种:异步任务时

 dispatch_queue_t queue1 = dispatch_queue_create("dispatchGroupMethod1.queue1", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group1 = dispatch_group_create(); dispatch_group_async(group1, queue1, ^{
dispatch_async(queue1, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-异步任务执行-:%ld",@"任务1",(long)i); }
});
}); dispatch_group_async(group1, queue1, ^{
dispatch_async(queue1, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-异步任务执行-:%ld",@"任务2",(long)i); }
});
}); // //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
// dispatch_group_wait(group1, DISPATCH_TIME_FOREVER); //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
dispatch_group_notify(group1, queue1, ^{
NSLog(@"Method1-全部任务执行完成");
});

异步任务运行结果:

-- ::28.889 MyTestWorkProduct[:] Method1-全部任务执行完成
-- ::29.893 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::29.893 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::30.896 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::30.896 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::31.901 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::31.901 MyTestWorkProduct[:] 任务1-异步任务执行-:

结论:dispatch_group_async(group, queue, block) 和 dispatch_group_notify(group1, queue1, block) 组合在执行同步任务时正常,在执行异步任务时不正常。

其二

dispatch_group_enter(group);

dispatch_group_leave(group);

dispatch_group_notify(group1, queue1,block);

在这种组合下,根据任务是同步、异步又分为两种,这两种组合的执行代码与运行结果如下:

第一种:同步任务时

 dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group2 = dispatch_group_create(); dispatch_group_enter(group2);
dispatch_sync(queue2, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-同步任务执行-:%ld",@"任务1",(long)i); }
dispatch_group_leave(group2);
}); dispatch_group_enter(group2);
dispatch_sync(queue2, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-同步任务执行-:%ld",@"任务2",(long)i); }
dispatch_group_leave(group2);
}); // //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
// dispatch_group_wait(group2, DISPATCH_TIME_FOREVER); //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
dispatch_group_notify(group2, queue2, ^{
NSLog(@"Method2-全部任务执行完成");
});

同步任务执行结果:

-- ::05.884 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::06.885 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::07.886 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::08.887 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::09.888 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::10.889 MyTestWorkProduct[:] 任务2-同步任务执行-:
-- ::10.889 MyTestWorkProduct[:] Method2-全部任务执行完成

第二种:异步任务时

   dispatch_queue_t queue2 = dispatch_queue_create("dispatchGroupMethod2.queue2", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group2 = dispatch_group_create(); dispatch_group_enter(group2);
dispatch_async(queue2, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-异步任务执行-:%ld",@"任务1",(long)i); }
dispatch_group_leave(group2);
}); dispatch_group_enter(group2);
dispatch_async(queue2, ^{
for (NSInteger i =; i<; i++) {
sleep();
NSLog(@"%@-异步任务执行-:%ld",@"任务2",(long)i); }
dispatch_group_leave(group2);
}); // //等待上面的任务全部完成后,会往下继续执行 (会阻塞当前线程)
// dispatch_group_wait(group2, DISPATCH_TIME_FOREVER); //等待上面的任务全部完成后,会收到通知执行block中的代码 (不会阻塞线程)
dispatch_group_notify(group2, queue2, ^{
NSLog(@"Method2-全部任务执行完成");
});

异步任务执行结果:

-- ::38.705 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::38.705 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::39.709 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::39.709 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::40.712 MyTestWorkProduct[:] 任务2-异步任务执行-:
-- ::40.712 MyTestWorkProduct[:] 任务1-异步任务执行-:
-- ::40.713 MyTestWorkProduct[:] Method2-全部任务执行完成

结论:

dispatch_group_enter(group)、dispatch_group_leave(group) 和  dispatch_group_notify(group1, queue1,block) 组合在执行同步任务时正常,在执行异步任务时正常。

dispatch_group_t 日常使用注意事项的更多相关文章

  1. Zookeeper从入门到精通(开发详解,案例实战,Web界面监控)

    ZooKeeper是Hadoop的开源子项目(Google Chubby的开源实现),它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.命名服务.分布式同步.组服务等. Zookee ...

  2. 超详细的HashMap解析(jdk1.8)

    目录 一.预备知识 时间复杂度 基本数据结构 基本位运算 二.HashMap实现原理 结构 速度 三.源码分析 基本常量 基本成员变量 构造方法 put方法 remove 四.日常使用注意事项 五.总 ...

  3. Oracle GoldenGate OGG管理员手册(较早资料)

    第一章 系统实现简述 前言 编写本手册的目的是为系统管理员以及相关操作人员提供 Oracle  Goldengat  软 件的日常维护和使用的技术参考: 3 ORACLE 第二章 OGG 日常维护操作 ...

  4. ZooKeeper_基础知识学习

    ZooKeeper是Hadoop的开源子项目(Google Chubby的开源实现),它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.命名服务.分布式同步.组服务等. Zookee ...

  5. Oracle GoldenGate OGG管理员手册

    第一章 系统实现简述 前言 编写本手册的目的是为系统管理员以及相关操作人员提供 Oracle  Goldengat  软 件的日常维护和使用的技术参考: 3 ORACLE 第二章 OGG 日常维护操作 ...

  6. 【转】Camera 简介

    一.摄像头(CAMERA)又称为电脑相机.电脑眼等,它作为一种视频输入设备,在过去被广泛的运用于视频会议.远程医疗及实时监控等方面. 近年以来,随着互联网技术的发展,网络速度的不断提高,再加上感光成像 ...

  7. 不可错过的效能利器「GitHub 热点速览 v.22.39」

    如果你是一名前端工程师且维护着多个网站,不妨试试本周榜上有名的 HTML-first 的 Qwik,提升网站访问速度只用一招.除了提升网站加载速度的 Qwik,本周周榜上榜的 Whisper 也是一个 ...

  8. ORACLE分区表梳理系列(二)- 分区表日常维护及注意事项(红字需要留意)

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  9. ORACLE分区表梳理系列(一)- 分区表概述、分类、使用方法及注意事项

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

随机推荐

  1. Remove Element leetcode

    Given an array and a value, remove all instances of that value in place and return the new length. T ...

  2. Android实现录屏直播(三)MediaProjection + VirtualDisplay + librtmp + MediaCodec实现视频编码并推流到rtmp服务器

    请尊重分享成果,转载请注明出处,本文来自Coder包子哥,原文链接:http://blog.csdn.net/zxccxzzxz/article/details/55230272 Android实现录 ...

  3. JavaScript零基础入门

    为什么学习JavaScript 1. 所有主流浏览器都支持JavaScript. 2. 目前,全世界大部分网页都使用JavaScript. 3. 它可以让网页呈现各种动态效果. 易学性 1.学习环境无 ...

  4. YIi2 Pjax简单使用

    1.点击事件需要在Pjax::begin() 和Pjax::end()范围内 2.需要在链接配置数组后加上  ['data-pjax'=>'#testPjax'] 其中,'#testPjax‘是 ...

  5. HTML5微数据

    本篇文章是一个纯搬运贴,原博主是在是做的太详细了 原贴地址:http://www.zhangxinxu.com/wordpress/2011/12/html5扩展-微数据-丰富网页摘要/ 一.微数据是 ...

  6. Dark的项链(树链剖分)

    P2272 - Dark的锁链 Description 无向图中有N个节点和两类边,一类边被称为主要边,而另一类被称为附加边.Dark有N – 1条主要边,并且Dark的任意两个节点之间都存在一条只由 ...

  7. [原创]HBase学习笔记(3)- Java程序访问HBase

    这里介绍使用java api来访问和操作HBase,例如create.delete.select.update等操作. 1.HBase配置 配置HBase使用的zookeeper集群地址和端口. pr ...

  8. HackerRank The Chosen One [预处理][gcd]

    题解:tags:[预处理][gcd]故事背景:光头钻进了茫茫人海.这是一个典型の通过前缀后缀和来降低复杂度的问题.先用pre数组与suf数组分别维护前缀gcd和后缀gcd.如果 a[i] % gcd( ...

  9. redis实现队列消息的ack

    由于公司提供的队列实在太过于蛋疼而且还限制不能使用其他队列,但为了保证数据安全性需要一个可以有ack功能的队列. 原生的redis中通过L/R PUSH/POP方式来实现队列的功能,这个当然是没办法满 ...

  10. [原]C#与非托管——初体验

    P/Invokes初看起来非常简单,利用DllImport进行extern函数的声明,程序就可以在调用extern函数的时候自动查询调用到对应的非托管函数,有些类似Java的native函数,但更为简 ...