文档章节

GCD知识

 泊竹
发布于 2014/05/04 13:45
字数 1220
阅读 123
收藏 1

Grand Central Dispatch =GDC

1.有两种:顺序的serial Dispatch Queue 与 并发的Concurrent Dispatch Queue
     前者是所有加入这个queue的block会顺序执行,完成一个在开始第二个。既此队列只开一个线程顺序执行。
     后者是所有加入这个queue的block会并发执行,第二个的开始与第一个是否结束无关,他会选择最有解决线程创建方案,不会每个block创建一个线程(比如b1,b2,b3当要执行b3的时候,b1执行完了,此时b3会加入b1的线程而不会重新创建)。

2.创建方式
     dispatch_queue_t xxx = dispatch_queue_create("queueName",Null) //这个是创建了serial Dispatch Queue
     dispatch_queue_t xxx = dispatch_queue_create("queueName",DISPATCH_QUEUE_CONCURRENT);//这个是创建concurrent dispatch queue
需要人工release

3.Main Dispatch Queue/Global Dispatch Queue
   Main Dispatch Queue 主线程队列 加入此线程的都会在主线程进行执行,既丢入NSRunLoop里。一般需要刷新页面相关的才会使用。
   Global Dispatch Queue 是做一个快速获取的Concurrent dispatch queue存在的,他有4个优先级 background,low,default,high
注意:使用MainDQ 和 GlobalDQ 是不需要进行retain 或release的 

4.dispatch_set_target_queue
     设置队列优先级。
dispatch_set_target_queue(Q1,Q2);
Q1为需要修改优先级的,Q2为Q1要与他同级的。
MainDQ 与GlobalDQ因为是全局 所以无法作为第一个参数。
     在必须将不可并行的处理追加到多个serial Dispatch Queue 中时,如果使用dispatch_set_target_queue函数将目标指定为某一个serialDispatchQueue即可防止处理并行执行。

5.dispatch_after 与 dispatch_walltime
     dispatch_after 为延迟多久加入队列(相对时间)
     dispatch_walltime 为在什么时间加入队列(绝对时间)
ex:
     dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,3ull * NSEC_PER_SEC);
     dispatch_after(time,dispatch_get_main_queue(),^{…});
     dispatch_time_t 是从第一个参数的时间开始,经历第二个参数的时长之后。
     ull 是C语言数值字面量
     NSEC_PER_SEC为秒为计数单位
     NSEC_PER_MSEC为毫秒的计数单位
     dispatch_walltime 返回的为dispatch_time_t

*6.Disptach Group
将dispatch 加入group,并且设置执行group队列完后的执行代码。
     ex:
     dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_DEFAULT,0);
dispatch_group_t group=disptach_group_create();
dispatch_group_async(group,queue,^{1...});
dispatch_group_async(group,queue,^{2...});
dispatch_group_async(group,queue,^{3...});
dispatch_group_notify(group,dispatch_get_main_queue(),^{结束后执行的});
dispatch_release(group);

注意:在dispatch_group_notify函数中不管指定怎么样的Dispatch Queue,属于Dispatch Group的处理在追加的block(上面例子的【结束后执行的】)时都已经结束。

另外还有dispatch_group_wait(group,DISPATCH_TIME_FOREVER);
这个表示 调用他的线程永远等待(因为第二个参数DISPATCH_TIME_FOREVER,如果是其他ex:disptach_time_t time=dispatch_time(DISPATCH_TIME_NOW,1ull*NSEC_PER_SEC);
dispatch_group_wait(group,time);
的话就是等待1秒) 
long result=dispatch_group_wait(……);
返回值为long型
if(result==0){
    // 等待时间结束后,group的全部处理执行结束
}else{
    // 等待时间结束后,group的还有未完成的处理
}

正常情况下不使用dispatch_group_wait,而使用dispatch_group_notify(group,dispatch_get_main_queue(),^{结束后执行的});
可以更好的简化代码。

7.dispatch_barrier_async
     为了规避Concurrent dispatch queue使用中的并发读取数据,数据竞争等问题。
使用dispatch_barrier_async
ex:
     queue 为Concurrent dispatch queue
     queue 其他处理1
     queue 其他处理2
     dispatch_barrier_async(queue,blk_for_writing)
     queue 其他处理3
     queue 其他处理4
     其他处理1 2 执行完 才会执行dispatch_barrier_async,dispatch_barrier_async执行完才会执行 其他处理 3 4
     如果其他处理都是数据库读操作  dispatch_barrier_async是数据库写操作,那么这样能保证 3 4 读取的数据是修改(写入)后的,数据保持正确。

8.dispatch_sync
     同步执行,与dispatch_async相反。此方法不能将block加到,mainQueue中,会导致死锁。也不能给Serial Dispatch Queue增加block,也会导致死锁。
     简单的说这个一般不用,用只用在Concurrent dispatch queue中。(其实一般不会用到)

9.dispatch_apply
     重复执行block,x次。
ex:     dispatch(10,queue,^{…block…});
          NSlog(@“done");
     重复执行block 10次,并且等待执行结束后才继续执行NSlog(@“done”)。
注意:dispatch_apply([array count],queue,^(size_t index){…block…});
     size_t index代表数组下标,上面代码会将数组array的每个下表都丢入block中执行一次。

10.dispatch_suspend/dispatch_resume
    dispatch_suspend 挂起已经追加的处理(未执行的处理暂不执行)
    dispatch_resume 恢复已经追加的处理

11.Dispatch Semaphore 
     代码性排他,通过计数器来限制当前代码在执行过程中只能有限的线程数执行。
创建:dispatch_semaphore_t semaphore=dispatch_semaphore_create(1);
创建一个dispatch_semaphore_t 并且初始化计数为1;

等待(此代码后开始限制线程(排他),加锁,并且计数-1)。
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

排他控制结束(解锁,并且计数+1)
disptach_semaphore_signal(semaphore);

12.Dispatch_once
     保证在应用程序执行过程中只执行一次的指令。
     static dispatch_once_t pred;s
dispatch_once(&pred, ^{……});

13.Dispatch I/O
     通过使用Dispatch I/O可以并发读写数据,提高效率

14.dispatch_queue 与 dispatch_source
     dispatch_queue是无法中断的,要么使用内部标志位。
     而dispatch_source 并且可以设置回调的cancel block。

本文转载自:http://poolo.iteye.com/blog/1998275

共有 人打赏支持
粉丝 90
博文 67
码字总数 13285
作品 0
徐汇
私信 提问
玩转iOS开发:iOS中的GCD开发(三)

文章分享至我的个人技术博客: cainrun.github.io/15019284409… 上一章, 我们了解到了里的一些队列和任务的知识, 也实践了一下, 同时我们也对主队列的一些小情况了解了一下, 比如上一章讲到的...

CainLuo
2017/08/13
0
0
iOS性能优化——图片加载和处理

前言 本文基于WWDC2018-Image and Graphics Best Practices,对图片加载和处理的思考和总结。 本文不是WWDC翻译,如果需要了解视频内容可以点击上面的链接观看。 正文 图片的显示分为三步:加...

落影loyinglin
10/14
0
0
据说这是高级iOS开发工程师的面试题

CALayer与UIView的区别是什么? GCD? TCP/UDP? socket链接与http连接? TCP的三次握手? iOS中对象之间有哪些通信方式? http协议的特点,GET请求与POST请求,https协议 XML与JSON数据解析...

萨斯辈的呼唤
2015/06/30
0
0
【欧拉定理+思维】UVA - 11426 GCD - Extreme (II)

版权声明:时间是有限的,知识是无限的,那就需要在有限的时间里最大化的获取知识。 https://blog.csdn.net/Firetocheat_/article/details/82946561 【欧拉定理+思维】UVA - 11426 GCD - Ext...

bryce1010
10/05
0
0
2018 Multi-University Training Contest 7

1001:Age of Moyu 1002:AraBellaC 枚举循环周期,对每个循环周期内的mxa,mnb,mxb,mnc二分寻找,要保证(mxa-1)%len<(mnb-1)%len和(mxb-1)%len<(mnc-1)%len。 000000"> 000000"> 000000">......

Hetui
08/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Git工作原理

git跟传统的代码管理器(如svn)不同, 主要区别在于git多了个本地仓库以及缓存区,所以即使无法联网也一样能提交代码。 术语解释: 工作区间: 即我们创建的工程文件, 在编辑器可直观显示;...

Lienson
12分钟前
1
0
MySQL驱动对应Server版本、JDK版本

昨日生产上线,临时升级MySQL版本,导致连接不上。 应用JDK版本1.5 测试环境MySQL版本5.7 驱动版本5.1.40.jar 正常 生产环境MySQL版本8.0 驱动版本5.1.40.jar 连接不上 生产环境MySQL版本8.0...

zcjlq
14分钟前
7
0
千万级规模【高性能、高并发】互联网架构经验分羹

架构以及我理解中架构的本质 在开始谈我对架构本质的理解之前,先谈谈对今天技术沙龙主题的个人见解,千万级规模的网站感觉数量级是非常大的,对这个数量级我们战略上 要重 视 它 , 战术上又...

java知识分子
14分钟前
0
0
重磅!阿里巴巴工程师获得 containerd 社区席位,与社区共建云时代容器标准

重磅!阿里巴巴工程师获得 containerd 社区席位,与社区共建云时代容器标准 11 月 29 日,CNCF containerd 社区正式宣布:两位阿里巴巴工程师正式获得 containerd 社区席位,成为 containerd...

阿里云官方博客
16分钟前
0
0
你会用哪些JavaScript循环遍历

总结JavaScript中的循环遍历 定义一个数组和对象 const arr = ['a', 'b', 'c', 'd', 'e', 'f'];const obj = { a: 1, b: 2, c: 3, d: 4} for() 经常用来遍历数组元素 遍历值为数组...

peakedness丶
17分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部