话不多说,先上代码,在分析

Code

- (void)viewDidLoad {
[super viewDidLoad]; dispatch_group_t group1 = dispatch_group_create();
dispatch_group_t group2 = dispatch_group_create(); NSLog(@"1,begin");
if (1)
{
[self func1WithGroup:group1];
dispatch_group_enter(group2);
dispatch_group_notify(group1, dispatch_get_global_queue(0, 0), ^{
NSLog(@"6, after group1 clear");
[self func2WithGroup:group2];
dispatch_group_leave(group2);
});
} //如果if中是0,那么也会执行,不会阻塞
//因为group对应的值是0
dispatch_group_notify(group2, dispatch_get_global_queue(0, 0), ^{
NSLog(@"9, after group2 clear");
[self finalFunc:group2];
});
NSLog(@"not blocking code ");
} - (void)func1WithGroup:(dispatch_group_t)group
{
dispatch_group_enter(group);
NSLog(@"2,after group1 enter");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"3,before group1 leave");
[NSThread sleepForTimeInterval:1];
dispatch_group_leave(group);
NSLog(@"5, after group1 leave"); });
} - (void)func2WithGroup:(dispatch_group_t)group
{
dispatch_group_enter(group);
NSLog(@"7,after group2 enter");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:1];
dispatch_group_leave(group);
NSLog(@"8, after group2 leave");
}); } - (void)finalFunc:(dispatch_group_t)group
{
NSLog(@"%@",NSStringFromSelector(_cmd));
}

输出如下

 1,begin
2,after group1 enter
not blocking code
3,before group1 leave
5, after group1 leave
6, after group1 clear
7,after group2 enter
8, after group2 leave
9, after group2 clear
finalFunc:

先熟悉几个概念

dispatch group 是 GCD 的一项特性,能够把任务分组。调用者可以等待这组任务执行完毕,也可以在提供回调函数之后继续往下执行,这组任务完成时,调用者会得到通知。

此外还有两个函数 dispatch_group_enterdispatch_group_leave

前者能够使分组里正要执行的任务数递增,而后者则使之递减。

dispatch_group_notify 这个函数,可以向此函数传入 block,等待 group 中任务数完成后,block 会在响应的队列中执行。

假如当前线程不应阻塞,而开发者又想在那些任务全部完成时得到通知,那么此做法就很有必要了。

代码分析

  1. 首先打印了 1,begin
  2. 同步调用了 func1WithGroup,打印了 2,after group1 enter
  3. 所有的函数都不是阻塞的,所有打印了not blocking code
  4. func1WithGroup 中全局队列得到调用,打印了3,before group1 leave5, after group1 leave
  5. 由于此前 group1 中任务数都不是 0,所以第一个 dispatch_group_notify 对应的 block 一直没有被调用。此时 group1 中任务被清空,此 block 被调用,打印了 6, after group1 clear
  6. block 中调用了 func2WithGroup,打印了 7,after group2 enter
  7. func2WithGroup 中 block 被调用,打印了 8, after group2 leave
  8. 由于调用了 dispatch_group_enter,此前 group2 中任务数目不是 0。此时被清空,group2 对应的 block 被调用,打印 9, after group2 clear
  9. 调用 finalFunc,打印方法名字 finalFunc

思考

  1. 利用 dispatch group 可以实现同步,也很方便把原来耗时操作放在异步线程中而不影响函数的调用时序,比如可以把全局队列的休眠函数换为文件读写。
  2. dispatch_group_enterdispatch_group_leave 要配对

参考

  • Matt Galloway, 爱飞翔. Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法[J]. 中国科技信息, 2014(6):131-131.

GCD 中使用 dispatch group 进行同步操作的更多相关文章

  1. 深入ObjC GCD中的dispatch group工作原理。

    本文是基于GCD的支持库libdispatch的源代码分析的结果或是用于作为源代码阅读的参考,尽量不帖代码,力求用UML图来说明工作流. 本文参考的源代码版本为v501.20.1,如有兴趣请自行到苹果 ...

  2. Swift中的GCD——常见的dispatch方法

    什么是GCD Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法.该方法在Mac OS X 10.6雪豹中首次推出,并随后被引入到了iOS4.0中.GCD ...

  3. GCD中的dispatch_group函数的详解

    <一>引入dispatch_group函数的目的 在追加到dispatch_Queue中的多个处理全部结束后想要执行结束的处理,这种需求经常会在我们的程序中出现 (第一种情况)只使用一个S ...

  4. GCD中的dispatch_apply的用法及作用

    GCD中的dispatch_apply的用法及作用 (一)dispatch_apply的基本用法 dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联A ...

  5. iOS开发-多线程之GCD(Grand Central Dispatch)

    Grand Central Dispatch(GCD)是一个强有力的方式取执行多线程任务,不管你在回调的时候是异步或者同步的,可以优化应用程序支持多核心处理器和其他的对称多处理系统的系统.开发使用的过 ...

  6. GCD中使用dispatch_after函数延迟处理任务

    在实际的开发中,经常会遇到想要在指定的时间间隔后执行某个处理 <一>在GCD中提供了dispatch_after函数来完成这一操作 dispatch_after(dispatch_time ...

  7. GCD (Grand Central Dispatch) 笔记

    GCD (Grand Central Dispatch) 是Apple公司开发的一种技术,它旨在优化多核环境中的并发操作并取代传统多线程的编程模式. 在Mac OS X 10.6和IOS 4.0之后开 ...

  8. iOS 关于GCD中的队列

    GCD中队列分类及获得方式 1.串行队列  dispatch_queue_t queue = dispatch_queue_create("队列名", DISPATCH_QUEUE ...

  9. MySQL中distinct和group by性能比较[转]

    MySQL中distinct和group by性能比较[转] 之前看了网上的一些测试,感觉不是很准确,今天亲自测试了一番.得出了结论(仅在个人计算机上测试,可能不全面,仅供参考) 测试过程: 准备一张 ...

随机推荐

  1. wcf数据推送

    http://www.cnblogs.com/artech/archive/2007/03/02/661969.html

  2. 2018.09.16 loj#10243. 移棋子游戏(博弈论)

    传送门 题目中已经给好了sg图,直接在上面跑出sg函数即可. 最后看给定点的sg值异或和是否等于0就判好了. 代码: #include<bits/stdc++.h> #define N 2 ...

  3. excel绝对引用中间添加符号

    =F1&"_"&J1 绝对引用 相对引用 按F4 然后复制全部,选择性黏贴,值和数字即可

  4. spring mvc 静态资源版本控制

    spring bean 文件中增加 <bean class="cn.zno.smse.common.context.VersionServletContext">< ...

  5. Android真机调试试验

    之前一直使用模拟器,很不好用,今天使用真机调试试验. 准备材料:电脑,Android手机. 首先,就遇到了一个问题,我的手机是华为的,之前不知道怎么回事,打开调试总是自动关闭,而且切换总是切换不了,老 ...

  6. VS 附加不上w3wp.exe

    今天调用VS 附加不上w3wp.exe,其他的站点都能附加上,就有一个站附加不上,找了各种可能都没有解决,结果发现是版本被编译成release了,原来的配置都是debug的,不知道被谁给改成relea ...

  7. Business Cards

    Problem Description Running a paper shop is not an easy job, especially with harsh customers. Today ...

  8. C++中的结构体的认识

    C++中的结构体的认识 1. typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间. 实例像:typedef ...

  9. 项目笔记---事半功倍之GhostDoc(二)

    前言 前一篇文章<项目笔记---事半功倍之StyleCop(一)>提到如何约束代码,规范代码风格,这一节,我们将了解如何快速生成符合规则的代码注释---GhostDoc 一.安装Ghost ...

  10. 前端项目打包工具weexpack的安装

    最下面是本人安装时候的系统环境,本篇文章只限于参考,不一定非得是这样,原因你懂得. 打包的过程中出现的问题 1.执行到weexpack run android的时候,到了resolving class ...