读书笔记【1】- Grand Central Dispatch


简答的复习了一下GCD的一些简单操作,这里做一个笔记,方便以后查看。

  • Dispatch Queue
    • 自定义串、并行队列
    • 程序进程缺省队列
    • 主线程队列
  • 同步/异步、串行/并行使用
  • 死锁问题
  • dispatch_after
  • dispatch_group

Dispatch Queue

  • Serial Dispatch Queue
    按添加进队列的顺序(先进先出)一个接一个的执行

  • Concurrent Dispatch Queue
    并发执行队列里的任务

1.1 自定义串、并行队列

并行队列:DISPATCH_QUEUE_CONCURRENT
串行队列:DISPATCH_QUEUE_SERIAL
//创建一个名称为‘com.company.xxx’的串行队列
dispatch_queue_t serialQueue = dispatch_queue_create("com.company.xxx", DISPATCH_QUEUE_SERIAL);

//创建一个名称为‘com.xxx’的并行队列
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.company.xxx", DISPATCH_QUEUE_CONCURRENT);

Note:
1)参数一是队列的名称,一般是使用倒序的全域名。虽然可以不给队列指定一个名称,但是有名称的队列可以让我们在遇到问题时更好调试
2)当参数二为nil时返回Serial Dispatch Queue(串行队列),如上面那个例子,当指定为DISPATCH_QUEUE_CONCURRENT时返回Concurrent Dispatch Queue(并行队列)

1.2 程序进程缺省队列

高优先级队列:DISPATCH_QUEUE_PRIORITY_HIGH
中优先级队列:DISPATCH_QUEUE_PRIORITY_DEFAULT
低优先级队列:DISPATCH_QUEUE_PRIORITY_LOW
//获取程序缺省并行队列,第二个参数固定为0
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

Note:
1)需要注意的是,三个队列不代表三个线程,可能会有更多的线程。并发队列可以根据实际情况来自动产生合理的线程数,也可理解为dispatch队列实现了一个线程池的管理,对于程序逻辑是透明的。
2)获取Global Dispatch Queue的时候可以指定优先级,可以根据自己的实际情况来决定使用哪种优先级

1.3 主线程队列

//获取主线程串行队列
dispatch_queue_t queue = dispatch_get_main_queue();

三者对比

队列 串行 并行
自定义队列
程序缺省队列 ×
主线程队列 ×

Note:
一般只在需要更新UI时我们才获取Main Dispatch Queue,其他情况下用Global Dispatch Queue就满足需求了

同步/异步、串行/并行使用

//异步执行block,函数立即返回
dispatch_async(queue, ^{

  //block具体代码

}); 

//同步执行block,函数不返回
dispatch_sync(queue, ^{

  //block具体代码

}); 

举例:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //子线程中开始网络请求数据
        ···
        //更新数据模型
        dispatch_sync(dispatch_get_main_queue(), ^{
            //在主线程中更新UI代码
            self.view.backgroundColor = [UIColor orangeColor];
        });
    });

Note:
尽可能避免使用dispatch_sync,嵌套使用时还容易引起程序死锁

死锁问题

  • 同步串行会出现死锁,同步并行不会造成死锁
  • 异步不管是串行还是并行都不会出现死锁
  • 异步嵌套同步或者同步嵌套异步就需要注意代码执行顺序

Note:
死锁原因:提交到主线程队列的时候,慎用同步dispatch_sync方法,有可能造成死锁。因为主线程队列是串行队列,要等队列里的任务一个一个执行。所以提交一个任务到队列,如果用同步方法就会阻塞住主线程,而主线程又要等主线程队列里的任务都执行完才能执行那个刚提交的,所以主线程队列里还有其他的任务的话,但他已经被阻塞住了,没法先完成队列里的其他任务,即,最后一个任务也没机会执行到,于是造成死锁。

dispatch_after

dispatch_after能让我们添加进队列的任务延时执行,比如想让一个Block在5秒后执行:

double delayTime = 5.0;

dispCatch_time_t dTime = dispatch_time(DISPATCH_TIME_NOW, 
(int64_t)(delayTime*NSEC_PER_SEC));

dispatch_after(dTime, dispatch_get_main_queue(), ^{
        //delayTime秒后执行block块
        NSLog(@"block执行");
    });

dispatch_after的真正含义是在5秒后把任务添加进队列中,并不是表示在5秒后执行,大部分情况该函数能达到我们的预期,只有在对时间要求非常精准的情况下才可能会出现问题


【拓展】
延迟执行还有另外一种方式,那就是NSObject中的performSelector:withObject:afterDelay:以及performSelector:withObject:afterDelay:inModes:


dispatch_group

我们现在有3个Block要执行,我们不在乎它们执行的顺序,我们只希望在这3个Block执行完之后再执行某个操作。这个时候就需要使用dispatch_group

dispatch_group_t groupQueue = dispatch_group_create();

dispatch_group_async(groupQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"1");
});

dispatch_group_async(groupQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"2");
});

dispatch_group_async(groupQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"3");
});

dispatch_group_notify(groupQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"completion");
});

在控制台打印的结果是:
2015-07-21 22:17:57.159 GCD[9606:1327380] 3
2015-07-21 22:17:57.159 GCD[9606:1327377] 2
2015-07-21 22:17:57.159 GCD[9606:1327379] 1
2015-07-21 22:17:57.159 GCD[9606:1327377] completion

Note:
输出的顺序与添加进队列的顺序无关,因为队列是Concurrent Dispatch Queue,但“completion”的输出一定是在最后的


再一次感谢您花费时间阅读这篇文章!

微博: @Danny_吕昌辉
博客: SuperDanny

2015 年 07月 15日

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容