GCD簡單使用

隊列類型

并發(fā)隊列(Concurrent Dispatch Queue)任務(wù)并發(fā)(同步)執(zhí)行
串行隊列(Serial Dispatch Queue)任務(wù)順序執(zhí)行
全局隊列(Global Queue)并發(fā)隊列
主隊列(Main Queue)串行隊列
    /**
     *  lable : 隊列名稱
     *  attr : 隊列類型晤揣,并發(fā)(ConCurrent),串行(Serial 或 NULL)
     */
    dispatch_queue_t conCurrentQueue = dispatch_queue_create("conCurrent", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_queue_t serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
    
    dispatch_queue_t serialQueue1 = dispatch_queue_create("serial1", NULL);

    /**
     *  全局并發(fā)隊列
     *  identifier : 優(yōu)先級
     *  flags      : 設(shè)置為0即可
     */
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    /**
     *  主隊列,串行隊列
     */
    dispatch_queue_t mainQueue = dispatch_get_main_queue();

執(zhí)行方式

同步執(zhí)行-在當(dāng)前線程執(zhí)行
異步執(zhí)行-在新線程執(zhí)行
queue:隊列
block:任務(wù)翎朱,需要進(jìn)行的操作
    //同步任務(wù)
    dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
    //異步任務(wù)
    dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)

代碼示例

  • 異步任務(wù) + 串行隊列

開啟新線程,串行執(zhí)行任務(wù)贸辈。

dispatch_queue_t serialCurrentQueue = dispatch_queue_create("myQueue", NULL);
    dispatch_async(serialCurrentQueue, ^{
        NSLog(@"串行隊列-異步任務(wù)1-%@", [NSThread currentThread]);
    });
    dispatch_async(serialCurrentQueue, ^{
        NSLog(@"串行隊列-異步任務(wù)2-%@", [NSThread currentThread]);
    });
    dispatch_async(serialCurrentQueue, ^{
        NSLog(@"串行隊列-異步任務(wù)3-%@", [NSThread currentThread]);
    });
    dispatch_async(serialCurrentQueue, ^{
        NSLog(@"串行隊列-異步任務(wù)4-%@", [NSThread currentThread]);
    });
    
    NSLog(@"執(zhí)行完成");
    /*
     執(zhí)行完成
     串行隊列-異步任務(wù)1-<NSThread: 0x7f9f32e1de80>{number = 2, name = (null)}
     串行隊列-異步任務(wù)2-<NSThread: 0x7f9f32e1de80>{number = 2, name = (null)}
     串行隊列-異步任務(wù)3-<NSThread: 0x7f9f32e1de80>{number = 2, name = (null)}
     串行隊列-異步任務(wù)4-<NSThread: 0x7f9f32e1de80>{number = 2, name = (null)}
     */
  • 異步任務(wù) + 并行隊列

開啟新線程王滤,同步執(zhí)行任務(wù)。

dispatch_queue_t conCurrentQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"并發(fā)隊列-異步任務(wù)1-%@", [NSThread currentThread]);
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"并發(fā)隊列-異步任務(wù)2-%@", [NSThread currentThread]);
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"并發(fā)隊列-異步任務(wù)3-%@", [NSThread currentThread]);
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"并發(fā)隊列-異步任務(wù)4-%@", [NSThread currentThread]);
    });
    
    NSLog(@"執(zhí)行完成");
    /*
     執(zhí)行完成
     并發(fā)隊列-異步任務(wù)1-<NSThread: 0x7fb751e1a6a0>{number = 5, name = (null)}
     并發(fā)隊列-異步任務(wù)3-<NSThread: 0x7fb751d08830>{number = 6, name = (null)}
     并發(fā)隊列-異步任務(wù)2-<NSThread: 0x7fb751d0ee50>{number = 2, name = (null)}
     并發(fā)隊列-異步任務(wù)4-<NSThread: 0x7fb751d0f340>{number = 4, name = (null)}
     
     或
     
     并發(fā)隊列-異步任務(wù)2-<NSThread: 0x7fb751d01d20>{number = 10, name = (null)}
     執(zhí)行完成
     并發(fā)隊列-異步任務(wù)1-<NSThread: 0x7fb751d06210>{number = 9, name = (null)}
     并發(fā)隊列-異步任務(wù)3-<NSThread: 0x7fb751d0f400>{number = 11, name = (null)}
     并發(fā)隊列-異步任務(wù)4-<NSThread: 0x7fb751d08830>{number = 8, name = (null)}
     */
  • 異步任務(wù) + 主線程

不開啟新線程鸟废,在主線程串行執(zhí)行任務(wù)。

dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_async(mainQueue, ^{
        NSLog(@"主隊列-異步任務(wù)1-%@", [NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
        NSLog(@"主隊列-異步任務(wù)2-%@", [NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
        NSLog(@"主隊列-異步任務(wù)3-%@", [NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
        NSLog(@"主隊列-異步任務(wù)4-%@", [NSThread currentThread]);
    });
    
    NSLog(@"執(zhí)行完成");
    /*
     執(zhí)行完成
     主隊列-異步任務(wù)1-<NSThread: 0x7f8ccb601ec0>{number = 1, name = main}
     主隊列-異步任務(wù)2-<NSThread: 0x7f8ccb601ec0>{number = 1, name = main}
     主隊列-異步任務(wù)3-<NSThread: 0x7f8ccb601ec0>{number = 1, name = main}
     主隊列-異步任務(wù)4-<NSThread: 0x7f8ccb601ec0>{number = 1, name = main}
     */
  • 同步任務(wù) + 串行隊列

不開啟新線程姑荷,串行執(zhí)行任務(wù)盒延。

dispatch_queue_t serialCurrentQueue = dispatch_queue_create("myQueue", NULL);
    
    dispatch_sync(serialCurrentQueue, ^{
        NSLog(@"串行隊列-同步任務(wù)1-%@", [NSThread currentThread]);
    });
    dispatch_sync(serialCurrentQueue, ^{
        NSLog(@"串行隊列-同步任務(wù)2-%@", [NSThread currentThread]);
    });
    dispatch_sync(serialCurrentQueue, ^{
        NSLog(@"串行隊列-同步任務(wù)3-%@", [NSThread currentThread]);
    });
    dispatch_sync(serialCurrentQueue, ^{
        NSLog(@"串行隊列-同步任務(wù)4-%@", [NSThread currentThread]);
    });
    
    NSLog(@"執(zhí)行完成");
    /*
     串行隊列-同步任務(wù)1-<NSThread: 0x7f99c8600190>{number = 1, name = main}
     串行隊列-同步任務(wù)2-<NSThread: 0x7f99c8600190>{number = 1, name = main}
     串行隊列-同步任務(wù)3-<NSThread: 0x7f99c8600190>{number = 1, name = main}
     串行隊列-同步任務(wù)4-<NSThread: 0x7f99c8600190>{number = 1, name = main}
     執(zhí)行完成
     */
  • 同步任務(wù) + 并行隊列

不開啟新線程,串行執(zhí)行任務(wù)鼠冕。

dispatch_queue_t conCurrentQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(conCurrentQueue, ^{
        NSLog(@"并發(fā)隊列-同步任務(wù)1-%@", [NSThread currentThread]);
    });
    dispatch_sync(conCurrentQueue, ^{
        NSLog(@"并發(fā)隊列-同步任務(wù)2-%@", [NSThread currentThread]);
    });
    dispatch_sync(conCurrentQueue, ^{
        NSLog(@"并發(fā)隊列-同步任務(wù)3-%@", [NSThread currentThread]);
    });
    dispatch_sync(conCurrentQueue, ^{
        NSLog(@"并發(fā)隊列-同步任務(wù)4-%@", [NSThread currentThread]);
    });
    
    NSLog(@"執(zhí)行完成");
    /*
     并發(fā)隊列-同步任務(wù)1-<NSThread: 0x7fc1d2d08820>{number = 1, name = main}
     并發(fā)隊列-同步任務(wù)2-<NSThread: 0x7fc1d2d08820>{number = 1, name = main}
     并發(fā)隊列-同步任務(wù)3-<NSThread: 0x7fc1d2d08820>{number = 1, name = main}
     并發(fā)隊列-同步任務(wù)4-<NSThread: 0x7fc1d2d08820>{number = 1, name = main}
     執(zhí)行完成
     */
  • 同步任務(wù) + 主隊列

阻塞主線程

dispatch_queue_t mainQueue = dispatch_get_main_queue();
    NSLog(@"任務(wù)開始");
    dispatch_sync(mainQueue, ^{
        NSLog(@"主隊列-同步任務(wù)1-%@", [NSThread currentThread]);
    });
    NSLog(@"執(zhí)行完成");
     /*主隊列等待同步任務(wù)完成添寺,同步任務(wù)等待主隊列執(zhí)行完,相互等待懈费,誰都完成不了计露。
     任務(wù)開始
     */

表格總結(jié)

全局、并發(fā)隊列 自建串行隊列 主隊列
同步任務(wù) 不開啟新線程;串行執(zhí)行任務(wù) 不開啟新線程憎乙;串行執(zhí)行任務(wù) 造成死鎖
異步任務(wù) 開啟新線程票罐;并發(fā)執(zhí)行任務(wù) 開啟新線程;串行執(zhí)行任務(wù) 不開啟新線程泞边;串行執(zhí)行任務(wù)


GCD調(diào)度組(線程組)

異步執(zhí)行多個任務(wù)该押,當(dāng)所有任務(wù)執(zhí)行完成后,再執(zhí)行某個任務(wù)阵谚。

代碼示例

GCD線程間通訊

主隊列=主線程=UI線程蚕礼,所有的界面刷新都需要在主線程進(jìn)行烟具,子線程完成操作后,拿到主線程奠蹬,在主線程進(jìn)行刷新界面朝聋。

dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    dispatch_async(queue, ^{
        //執(zhí)行耗時任務(wù)
        //...
       
        dispatch_async(dispatch_get_main_queue(), ^{
            //在主線程進(jìn)行界面刷新
            //...
        });
    });

GCD延時函數(shù)

//第一種
    [self performSelector:@selector(showMessage) withObject:nil afterDelay:2.0f];
    
    //第二種
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //2秒后執(zhí)行的操作
        //...
    });

GCD執(zhí)行一次函數(shù)

提示方法
static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //只需要執(zhí)行一次的代碼
        //...
    });

GCD柵欄函數(shù)

在并發(fā)隊列插入柵欄函數(shù),會先執(zhí)行柵欄函數(shù)之前的操作罩润,再執(zhí)行柵欄函數(shù)玖翅,最后執(zhí)行柵欄函數(shù)后面的操作,起到柵欄的作用割以。

dispatch_queue_t queue = dispatch_queue_create("name", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        NSLog(@"耗時操作1-%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"耗時操作2-%@", [NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"柵欄函數(shù)-%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"耗時操作3-%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"耗時操作4-%@", [NSThread currentThread]);
    });
    
    NSLog(@"執(zhí)行完成");
    /*
     執(zhí)行完成
     耗時操作2-<NSThread: 0x7ff4b2dad620>{number = 2, name = (null)}
     耗時操作1-<NSThread: 0x7ff4b2c04bc0>{number = 3, name = (null)}
     柵欄函數(shù)-<NSThread: 0x7ff4b2c04bc0>{number = 3, name = (null)}
     耗時操作4-<NSThread: 0x7ff4b2dad620>{number = 2, name = (null)}
     耗時操作3-<NSThread: 0x7ff4b2c04bc0>{number = 3, name = (null)}
     */

GCD-dispatch_apply()函數(shù)

提交任務(wù)到隊列中多次執(zhí)行金度,由隊列決定并行還是串行。dispatch_apply為同步任務(wù)严沥,執(zhí)行完dispatch_apply才會執(zhí)行下面的操作猜极。

/*   iterations 執(zhí)行的次數(shù)
     queue      提交到的隊列
     size_t     索引,需要自己指定一個參數(shù)
     block      執(zhí)行的任務(wù)

     dispatch_apply(size_t iterations, dispatch_queue_t queue, <#^(size_t)block#>)
*/
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    
    dispatch_apply(4, globalQueue, ^(size_t index) {
       //執(zhí)行的循環(huán)操作
        NSLog(@"次數(shù)%d-%@", index, [NSThread currentThread]);
        
    });
    NSLog(@"執(zhí)行完成");
    /*
     次數(shù)0-<NSThread: 0x7f9da35020d0>{number = 1, name = main}
     次數(shù)1-<NSThread: 0x7f9da340be60>{number = 2, name = (null)}
     次數(shù)3-<NSThread: 0x7f9da3740740>{number = 4, name = (null)}
     次數(shù)2-<NSThread: 0x7f9da3608440>{number = 3, name = (null)}
     執(zhí)行完成
     */

參考
多線程----GCD的基本使用
多線程----GCD的常用函數(shù)和單例模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末消玄,一起剝皮案震驚了整個濱河市跟伏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌翩瓜,老刑警劉巖受扳,帶你破解...
    沈念sama閱讀 212,222評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異兔跌,居然都是意外死亡勘高,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評論 3 385
  • 文/潘曉璐 我一進(jìn)店門坟桅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來华望,“玉大人,你說我怎么就攤上這事仅乓±抵郏” “怎么了?”我有些...
    開封第一講書人閱讀 157,720評論 0 348
  • 文/不壞的土叔 我叫張陵夸楣,是天一觀的道長宾抓。 經(jīng)常有香客問我,道長裕偿,這世上最難降的妖魔是什么洞慎? 我笑而不...
    開封第一講書人閱讀 56,568評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮嘿棘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘旭绒。我一直安慰自己鸟妙,他們只是感情好焦人,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著重父,像睡著了一般花椭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上房午,一...
    開封第一講書人閱讀 49,879評論 1 290
  • 那天矿辽,我揣著相機(jī)與錄音,去河邊找鬼郭厌。 笑死袋倔,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的折柠。 我是一名探鬼主播宾娜,決...
    沈念sama閱讀 39,028評論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼扇售!你這毒婦竟也來了前塔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,773評論 0 268
  • 序言:老撾萬榮一對情侶失蹤承冰,失蹤者是張志新(化名)和其女友劉穎华弓,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體困乒,經(jīng)...
    沈念sama閱讀 44,220評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寂屏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了顶燕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凑保。...
    茶點(diǎn)故事閱讀 38,697評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖涌攻,靈堂內(nèi)的尸體忽然破棺而出欧引,到底是詐尸還是另有隱情,我是刑警寧澤恳谎,帶...
    沈念sama閱讀 34,360評論 4 332
  • 正文 年R本政府宣布芝此,位于F島的核電站,受9級特大地震影響因痛,放射性物質(zhì)發(fā)生泄漏婚苹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評論 3 315
  • 文/蒙蒙 一鸵膏、第九天 我趴在偏房一處隱蔽的房頂上張望膊升。 院中可真熱鬧,春花似錦谭企、人聲如沸廓译。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽非区。三九已至瓜挽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間征绸,已是汗流浹背久橙。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留管怠,地道東北人淆衷。 一個月前我還...
    沈念sama閱讀 46,433評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像排惨,于是被迫代替她去往敵國和親吭敢。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評論 2 350

推薦閱讀更多精彩內(nèi)容