GCD

GCD

Grand Central Dispatch是异步执行任务的技术之一。
GCD是苹果公司为多核的并行运算提出的解决方案
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

一个例子
  dispatch_async(queue, ^{
       
        /*
         *长时间处理
         */
        
        /*
         *长时间处理结束,主线程使用该处理结果
         *
         */
        dispatch_async(dispatch_get_main_queue(), ^{
            /*
             *只在主线程中可以执行的结果
             *例如  更新UI
             */
        });
    });
    其中queue是队列
    block是任务

在多线程编程中容易发生各种问题。比如多线程更新相同的数据、死锁、使用线程太多大量消耗内存等。采用GCD技术大大简化了复杂的多线程编程

Dispatch Queue

开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中。

dispatch_async(queue, ^{ 
        /*
         *想执行的任务
         */
    });

任务的取出遵循队列的FIFO原则:先进先出,后进后出。
另外在执行处理的时候存在两种Dispatch Queue,一种是等待现在执行中处理的Serial Dispatch Queue,另一种是不等待现在执行中处理的Concurrent Dispatch Queue。


并行视图
并行视图
串行视图
串行视图

创建 dispatch_queue_create()

dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)

dispatch_queue_t queue = dispatch_queue_create("gcd", NULL);
dispatch_queue_create("gcd", DISPATCH_QUEUE_CONCURRENT)

注意:系统对于一个Serial Dispatch Queue就只生成并使用一个线程。如果生成200个Serial Dispatch Queue,那么就生成200个线程
但是每个queue里面的多个任务还是一个一个的执行。
多个线程更新相同数据是可以使用Serial Dispatch Queue

Main Dispatch Queue/Global Dispatch Queue

dispatch_get_main_queue();
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
           
            //可并行执行的处理
            dispatch_async(dispatch_get_main_queue(), ^{
               //主线程中处理
            });
        });

dispatch_set_target_queue

dispatch_queue_create()生成的Queue,使用与默认优先级Global Dispatch Queue相同执行优先级的线程。而变更生成的Queue的执行优先级需要使用dispatch_set_target_queue这个函数

dispatch_set_target_queue(<#dispatch_object_t object#>, <#dispatch_queue_t queue#>)
指定第一个Queue与第二个Queue相同的优先级。

dispatch_after

在1s后将指定的block追加到Main Queue中执行

dispatch_after函数是指定时间追加而不是指定时间处理


 dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC);
    dispatch_after(time, dispatch_get_main_queue(), ^{
        NSLog(@"wait");
    });

Dispatch Group

在追加到Dispatch Queue中的多个处理全部结束之后想执行结束处理,这种会经常出现。在使用Current Dispatch的情况下使用Dispatch Group就可以实现

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"hehe1");
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"hehe2");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"hehe3");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"hehe4");
    });
    dispatch_group_notify(group, queue, ^{
        NSLog(@"over");
    });
2016-06-09 17:21:02.564 GCD[2874:227806] hehe3
2016-06-09 17:21:02.564 GCD[2874:227802] hehe2
2016-06-09 17:21:02.564 GCD[2874:227804] hehe1
2016-06-09 17:21:02.564 GCD[2874:227813] hehe4
2016-06-09 17:21:02.565 GCD[2874:227813] over

多个线程并行执行,所以追加处理执行的顺序不定,但是 over一定在最后才执行这里有一个好例子给大家

Dispatch Semaphore

Dispatch Semaphore是持有计数的信号,该基数是多线程编程中的计数信号类型。当计数为0时等待,计数为1或者大于1,减去1而不等待。

//创建一个计数为0的信号
 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    NSMutableArray *muArray = [[NSMutableArray alloc] init];
        dispatch_async(queue, ^{
            for (int i=0; i<100; i++) {
                [muArray addObject:@(i)];
            }
            dispatch_semaphore_signal(semaphore);  //计数+1
        });
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    NSLog(@"===>%d",[muArray count]);
    2016-06-09 17:49:14.300 GCD[2984:246535] ===>100
    如果没有则Dispatch Semaphore
    2016-06-09 17:57:55.160 GCD[3023:249929] ===>0

上例中创建一个计数为0的信号 等待

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);等待Dispatch Semaphore计数达到大于或者等于1。当计数达到或者大于1是,对该计数进行减法并从dispatch_semaphore_wait函数返回
通过dispatch_semaphore_signal(semaphore); 将Dispatch Semaphore计数+1

一个大神的GCD封装

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

推荐阅读更多精彩内容

  • 最近颇花了一番功夫把多线程GCD人的一些用法总结出来,一来帮自己巩固一下知识、二来希望能帮到对这一块还迷茫...
    人活一世阅读 273评论 1 1
  • 章节目录 什么是GCD? 如何在多条路径中执行CPU命令列? 即使多线程存在很多问题(如数据竞争、死锁、线程过多消...
    DrunkenMouse阅读 843评论 1 13
  • 多线程概念 线程线程指的是:1个CPU执行的CPU命令列为一条无分叉路径 多线程这种无分叉路径不止一条,存在多条即...
    我系哆啦阅读 567评论 0 5
  • 悠然飘叶阅读 171评论 1 1
  • 从开始到现在,你知道自己为什么是这个样子吗? 今天早上说服儿子跟随我一起去洪山区文化大厦观看一场公益演出,因为我有...
    知子花开阅读 221评论 0 2