一、背景简介
平时在进行多线程处理任务时,有时候希望多个任务之间存在着一种联系,希望在所有的任务执行完后做一些总结性处理。
那么就可以将多个任务放在一个任务组中进行统一管理。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. 2761: [JLOI2011]不重复数字(平衡树)

    2761: [JLOI2011]不重复数字 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2133  Solved: 825[Submit][Stat ...

  2. android开发艺术探索读书笔记之-------view的事件分发机制

    View的点击事件的分发,其实就是对MotionEvent事件的分发过程,即当一个MotionEvent产生后,系统需要把这个事件传递给一个具体的View,而这个过程就是分发过程. 分发过程主要由以下 ...

  3. bootstrap常见类的总结

    相信大家和我一样,曾经找过bootstrap的类名定义. 无奈没有找到现成的,那我就来总结一下常见类名吧. 基础样式:btn,alert,form,table,input,select.textare ...

  4. python中的列表list

    序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置类型,但最常见的是列表和元组. 序列 ...

  5. vpn的实现原理

    由于公共IP的短缺,我们在组建局域网时,通常使用保留地址作为内部IP,(比如最常用的C类保留地址:192.168.0.0-192.168.255.255)这些地址是不会被互联网分配的,因此它们在互联网 ...

  6. Java字节流在Android中的使用

    引言:项目开发有时会使用上传文件到服务器,再从服务器取数据显示到本地这一过程:或者输入一段文字,再把文字显示出来.这个过程都用到了IO流. IO流分为字符流(Reader\Writer)和字节流(In ...

  7. Spring初识(通过小实例清晰认识Spring)

    1.spring架构: spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,iba ...

  8. 转载 webstrom识别 React语法

    对于程序员而言:驼峰和下划线之间是一场宗派战争:大括号是否换行会成为一种党派:逗号写在行尾还是行首的人来自不同星球-- 然而,无规矩不成方圆,任何一个团队,要想有高质量的产出,第一步必须要对一些基本的 ...

  9. express创建网站

    Express 在初始化一个项目的时候需要指定模板引擎,默认支持Jade和ejs. 这里我们使用ejs模板引擎:(关于ejs的介绍可以先从百科里面了解一个大概)EJS是一个JavaScript模板库, ...

  10. centOS下调整swap

    [root@localhost /]# mkdir swap [root@localhost /]# cd swap [root@localhost swap]# dd if=/dev/zero of ...