GCD 中使用 dispatch group 进行同步操作
话不多说,先上代码,在分析
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_enter 和 dispatch_group_leave
前者能够使分组里正要执行的任务数递增,而后者则使之递减。
dispatch_group_notify 这个函数,可以向此函数传入 block,等待 group 中任务数完成后,block 会在响应的队列中执行。
假如当前线程不应阻塞,而开发者又想在那些任务全部完成时得到通知,那么此做法就很有必要了。
代码分析
- 首先打印了
1,begin。 - 同步调用了
func1WithGroup,打印了2,after group1 enter。 - 所有的函数都不是阻塞的,所有打印了
not blocking code。 func1WithGroup中全局队列得到调用,打印了3,before group1 leave及5, after group1 leave。- 由于此前
group1中任务数都不是 0,所以第一个dispatch_group_notify对应的 block 一直没有被调用。此时group1中任务被清空,此 block 被调用,打印了6, after group1 clear。 - block 中调用了
func2WithGroup,打印了7,after group2 enter。 func2WithGroup中 block 被调用,打印了8, after group2 leave。- 由于调用了
dispatch_group_enter,此前group2中任务数目不是 0。此时被清空,group2对应的 block 被调用,打印9, after group2 clear。 - 调用
finalFunc,打印方法名字finalFunc
思考
- 利用 dispatch group 可以实现同步,也很方便把原来耗时操作放在异步线程中而不影响函数的调用时序,比如可以把全局队列的休眠函数换为文件读写。
dispatch_group_enter和dispatch_group_leave要配对
参考
- Matt Galloway, 爱飞翔. Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法[J]. 中国科技信息, 2014(6):131-131.
GCD 中使用 dispatch group 进行同步操作的更多相关文章
- 深入ObjC GCD中的dispatch group工作原理。
本文是基于GCD的支持库libdispatch的源代码分析的结果或是用于作为源代码阅读的参考,尽量不帖代码,力求用UML图来说明工作流. 本文参考的源代码版本为v501.20.1,如有兴趣请自行到苹果 ...
- Swift中的GCD——常见的dispatch方法
什么是GCD Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法.该方法在Mac OS X 10.6雪豹中首次推出,并随后被引入到了iOS4.0中.GCD ...
- GCD中的dispatch_group函数的详解
<一>引入dispatch_group函数的目的 在追加到dispatch_Queue中的多个处理全部结束后想要执行结束的处理,这种需求经常会在我们的程序中出现 (第一种情况)只使用一个S ...
- GCD中的dispatch_apply的用法及作用
GCD中的dispatch_apply的用法及作用 (一)dispatch_apply的基本用法 dispatch_apply函数是dispatch_sync函数和Dispatch Group的关联A ...
- iOS开发-多线程之GCD(Grand Central Dispatch)
Grand Central Dispatch(GCD)是一个强有力的方式取执行多线程任务,不管你在回调的时候是异步或者同步的,可以优化应用程序支持多核心处理器和其他的对称多处理系统的系统.开发使用的过 ...
- GCD中使用dispatch_after函数延迟处理任务
在实际的开发中,经常会遇到想要在指定的时间间隔后执行某个处理 <一>在GCD中提供了dispatch_after函数来完成这一操作 dispatch_after(dispatch_time ...
- GCD (Grand Central Dispatch) 笔记
GCD (Grand Central Dispatch) 是Apple公司开发的一种技术,它旨在优化多核环境中的并发操作并取代传统多线程的编程模式. 在Mac OS X 10.6和IOS 4.0之后开 ...
- iOS 关于GCD中的队列
GCD中队列分类及获得方式 1.串行队列 dispatch_queue_t queue = dispatch_queue_create("队列名", DISPATCH_QUEUE ...
- MySQL中distinct和group by性能比较[转]
MySQL中distinct和group by性能比较[转] 之前看了网上的一些测试,感觉不是很准确,今天亲自测试了一番.得出了结论(仅在个人计算机上测试,可能不全面,仅供参考) 测试过程: 准备一张 ...
随机推荐
- UI设计:掌握这6点,轻松0到1
非科班出身能成为UI设计师吗? 答案是肯定的.世上无难事,只怕有心人.只要找对方法.坚持不懈,即便是零基础也能学好UI设计. 那么零基础学习UI设计,需要学习哪些知识?我们要从哪些地方学起?怎么系统学 ...
- postman模拟登录接口
https://blog.csdn.net/qq_22219911/article/details/80235272
- c:param 标签后不要写 注释 。否则报错 Encountered illegal body of tag "c:import" tag, given its attributes
c:param 标签后不要写 注释 .否则报错 Encountered illegal body of tag "c:import" tag, given its attribu ...
- cocos2d-js 安卓自定义本地通知功能
安卓新手,笔记有理解不当的地方望指出,经过几天折腾终于可以实现类似ios的本地通知功能(ios就几行代码),可能有第三方sdk可以方便实现,暂时没去找 思路: 1. startService 和bin ...
- 【Web】网站主如何更改网页标签的图标(favicon.ico)
修改web项目的favicon图标,方式有两种:全局方式和局部方式 全局方式: 进入服务器\webapps\ROOT,然后用自己的favicon.ico替换服务器自带的favicon.ico图片 局部 ...
- 2018.09.19 atcoder AtCoDeer and Election Report(贪心)
传送门 很有意思的一道贪心. 就是每次翻最小的倍数来满足条件. 代码: #include<bits/stdc++.h> #define ll long long using namespa ...
- python 实现排列组合
1.python语言简单.方便,其内部可以快速实现排列组合算法,下面做简单介绍. 2.一个列表数据任意组合 2.1主要是利用自带的库 #_*_ coding:utf-8 _*_ #__author__ ...
- nodejs 获取文件的编码方式
使用nodejs获取文件夹内文件的编码方式:使用jschardet模块. 下面的代码还有问题,没有添加结束的语句,没有判断应该在哪执行res.send(). res.send()不能放在forEach ...
- java对redis的基本操作(一)
一.server端安装 1.下载 https://github.com/MSOpenTech/redis 可看到当前可下载版本:redis2.6
- 成员函数指针与高性能C++委托
1 引子 标准C++中没有真正的面向对象的函数指针.这一点对C++来说是不幸的,因为面向对象的指针(也叫做“闭包(closure)”或“委托(delegate)”)在一些语言中已经证明了它宝贵的价值. ...