常用GCDAPI整理(二)

先列一下本篇文章所整理的提綱
1.GCD的延遲運行
2.使用Dispatch_group進行線程同步處理
3.使用dispatch_barrier函數(shù)(柵欄函數(shù))給訪問對象加同步鎖
4.同步執(zhí)行隊列函數(shù)dispatch_sync
5.使用dispatch_apply遍歷數(shù)組執(zhí)行任務
一湖雹、GCD延遲執(zhí)行
我們在工作中有可能回碰到需要延遲執(zhí)行某些命令的需求。在學習GCD之前我們可以通過

[self performSelector:@selector(abc:) withObject:nil afterDelay:2];

來延遲執(zhí)行某些任務棚瘟。但是使用這些方法有一些不方便的地方雅镊。首先可以帶的參數(shù)比較少。第二就是在不同線程中執(zhí)行的時候不如GCD方便殷勘。
使用GCD的方法如下椰苟、

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"test");
    });

方法講解:1.參數(shù)dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)代表從當前的時間延遲3s后執(zhí)行
DISPATCH_TIME_NOW代表從當前時間磁餐。
類似的還有DISPATCH_TIME_FOREVER這個通常用在等待某些方法執(zhí)行完成的時候使用例如dispatch_wait函數(shù)來判斷添加到隊列中的任務是否已經完成。
2.參數(shù)2決定在什么隊列中執(zhí)行要添加到隊列中的任務幼衰。本例中代表被添加的輸出test字符串在主線程中運行靴跛。
二、dispatch_group函數(shù)
使用場景:項目中的任務執(zhí)行在很多情況下是有順序的渡嚣。例如對任務B對數(shù)據(jù)進行緩存執(zhí)行之前梢睛。可能需要調用兩個數(shù)據(jù)請求獲得數(shù)據(jù)X和數(shù)據(jù)Y识椰。當數(shù)據(jù)X和Y同時完成了數(shù)據(jù)請求之后绝葡。才能執(zhí)行任務B。我們自然可以使用串行隊列裤唠。按照X->Y->B的任務添加順序去執(zhí)行任務。但是某些任務可能非常耗時莹痢。這樣會浪費大量的時間种蘸。而且不能有效的利用系統(tǒng)提供的多線程技術來加快任務的執(zhí)行速度。這顯然是不合適的竞膳。在這種情況下Dispatc_group就排上用場了航瞭。
我們可以使用多線程取獲取X和Y然后當X、Y都完成的時候再去執(zhí)行B坦辟。
使用代碼如下:

    dispatch_queue_t queueGlobal = dispatch_queue_create("globalQueue", DISPATCH_QUEUE_CONCURRENT);
//創(chuàng)建一個并行隊列
    dispatch_group_t groupBase = dispatch_group_create();
//創(chuàng)建一個Dispatch_group
    dispatch_group_async(groupBase, queueGlobal, ^{
       //任務X
        for (NSInteger i = 0; i < 10; i++){
            if (i == 9) NSLog(@"X馬上執(zhí)行完成");
        }
    });
//異步將任務X添加到groupBase的queueGlobal隊列上
    dispatch_group_async(groupBase, queueGlobal, ^{
        //任務Y
        for (NSInteger i = 0; i < 10; i++){
            if (i == 9) NSLog(@"Y馬上執(zhí)行完成");
        }
    });
//異步將任務Y添加到groupBase的queueGlobal隊列上
    dispatch_group_notify(groupBase, queueGlobal, ^{
        //任務B
        NSLog(@"B任務開始執(zhí)行");
    });
//等待groupBase上的任務執(zhí)行完成的時候執(zhí)行任務B

調試輸出框輸出為
2018-01-17 23:14:14.592177+0800 GCD二[16104:486560] X馬上執(zhí)行完成
2018-01-17 23:14:14.593407+0800 GCD二[16104:486558] Y馬上執(zhí)行完成
2018-01-17 23:14:14.601304+0800 GCD二[16104:486560] B任務開始執(zhí)行
通過以上我們可以清晰的分析得出刊侯。通過dispatch_group可以對并行隊列進行線程同步處理
(2)dispatch_group_wait函數(shù)分析
等待dispatch_group執(zhí)行完成除了可以使用dispatch_group_notify還可以使用dispatch_group_wait函數(shù)。使用如下

    dispatch_queue_t queueGlobal = dispatch_queue_create("globalQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t groupBase = dispatch_group_create();
    dispatch_group_async(groupBase, queueGlobal, ^{
       //任務X
        for (NSInteger i = 0; i < 10; i++){
            if (i == 9) NSLog(@"X馬上執(zhí)行完成");
        }
    });
    dispatch_group_async(groupBase, queueGlobal, ^{
        //任務Y
        for (NSInteger i = 0; i < 10; i++){
            if (i == 9) NSLog(@"Y馬上執(zhí)行完成");
        }
    });
    BOOL isComplete = dispatch_group_wait(groupBase, DISPATCH_TIME_FOREVER);
    NSLog(@"%d",isComplete);

調試輸出為
2018-01-17 23:20:16.809152+0800 GCD二[16145:489420] Y馬上執(zhí)行完成
2018-01-17 23:20:16.809152+0800 GCD二[16145:489418] X馬上執(zhí)行完成
2018-01-17 23:20:16.812577+0800 GCD二[16145:489332] 0
DISPATCH_TIME_FOREVER代表一直等待下去直到dispatch_group中的任務執(zhí)行完成锉走。等待期間執(zhí)行dispatch_group_wait函數(shù)的線程(當前線程)會一直被堵塞滨彻。而dispatch_group_notify則不會。所以我們平時在使用中還是多使用dispatch_group_notify函數(shù)比較好挪蹭。
三亭饵、dispatch_barrier_async柵欄函數(shù)的使用
在運行一些耗時操作的時候。使用多線程技術我們可以極大的提高我們的任務執(zhí)行效率梁厉。但是使用多線程技術也會帶來一些問題辜羊。比如對一些數(shù)據(jù)進行寫入操作。
1.對同一個數(shù)據(jù)不能夠同時執(zhí)行兩次寫入操作,
2.在進行寫入過程的時候能夠加上同步鎖词顾。拒絕執(zhí)行讀取操作八秃。
但是我們又不想舍棄多線程技術。在這種情景下dispatch_barrier_async函數(shù)就派上用上了肉盹。
使用如下:
objectA.h

#import <Foundation/Foundation.h>
@interface ObjectA : NSObject
@property (nonatomic, copy) NSString *baseString;
@end

ViewController.m

ObjectA *object = [[ObjectA alloc]init];
    object.baseString = @"testABC";
    dispatch_queue_t globalDefaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    for (NSInteger i = 0; i < 20; i++){
        dispatch_async(globalDefaultQueue, ^{
            NSLog(@"%@ ---  %ld",object.baseString,i);
        });
        if (i == 10){
            dispatch_barrier_async(globalDefaultQueue, ^{
                object.baseString = @"ABC";
            });
        }
    }

執(zhí)行結果如下:
2018-01-17 23:35:01.010879+0800 GCD二[16289:497032] testABC --- 10
2018-01-17 23:35:01.008748+0800 GCD二[16289:497017] testABC --- 2
2018-01-17 23:35:01.008760+0800 GCD二[16289:497016] testABC --- 3
2018-01-17 23:35:01.008921+0800 GCD二[16289:497025] testABC --- 4
2018-01-17 23:35:01.009424+0800 GCD二[16289:497026] testABC --- 5
2018-01-17 23:35:01.009437+0800 GCD二[16289:497027] testABC --- 6
2018-01-17 23:35:01.009864+0800 GCD二[16289:497029] testABC --- 7
2018-01-17 23:35:01.010640+0800 GCD二[16289:497031] testABC --- 8
2018-01-17 23:35:01.010659+0800 GCD二[16289:497030] testABC --- 9
2018-01-17 23:35:01.008200+0800 GCD二[16289:497015] testABC --- 0
2018-01-17 23:35:01.008227+0800 GCD二[16289:497014] testABC --- 1
2018-01-17 23:35:01.011883+0800 GCD二[16289:497033] ABC --- 11
2018-01-17 23:35:01.012994+0800 GCD二[16289:497034] ABC --- 12
2018-01-17 23:35:01.013015+0800 GCD二[16289:497035] ABC --- 13
2018-01-17 23:35:01.013565+0800 GCD二[16289:497036] ABC --- 14
2018-01-17 23:35:01.014066+0800 GCD二[16289:497037] ABC --- 15
2018-01-17 23:35:01.014870+0800 GCD二[16289:497038] ABC --- 16
2018-01-17 23:35:01.029353+0800 GCD二[16289:497039] ABC --- 17
2018-01-17 23:35:01.030392+0800 GCD二[16289:497040] ABC --- 18
2018-01-17 23:35:01.030875+0800 GCD二[16289:497041] ABC --- 19
我們可以得出結論昔驱。在同一個線程中通過柵欄函數(shù)執(zhí)行的時候∩先蹋可以自動同步鎖防止在進行寫入數(shù)據(jù)的時候對同一個數(shù)據(jù)讀取舍悯。保證了數(shù)據(jù)的正確性航棱。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市萌衬,隨后出現(xiàn)的幾起案子饮醇,更是在濱河造成了極大的恐慌,老刑警劉巖秕豫,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朴艰,死亡現(xiàn)場離奇詭異,居然都是意外死亡混移,警方通過查閱死者的電腦和手機祠墅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歌径,“玉大人毁嗦,你說我怎么就攤上這事』仡酰” “怎么了狗准?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長茵肃。 經常有香客問我腔长,道長,這世上最難降的妖魔是什么验残? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任捞附,我火速辦了婚禮,結果婚禮上鸟召,老公的妹妹穿的比我還像新娘氨鹏。我一直安慰自己喻犁,他們只是感情好肢础,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布传轰。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上梳星,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天异袄,我揣著相機與錄音玛臂,去河邊找鬼。 笑死,一個胖子當著我的面吹牛泡徙,可吹牛的內容都是我干的堪藐。 我是一名探鬼主播庶橱,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼贪惹,長吁一口氣:“原來是場噩夢啊……” “哼苏章!你這毒婦竟也來了奏瞬?” 一聲冷哼從身側響起并淋,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤镣典,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后澎剥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赶舆,經...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡倡蝙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了征炼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谆奥。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡魄懂,死狀恐怖缀拭,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情褐荷,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布嘹悼,位于F島的核電站叛甫,受9級特大地震影響,放射性物質發(fā)生泄漏杨伙。R本人自食惡果不足惜其监,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缀台。 院中可真熱鬧棠赛,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至辩涝,卻和暖如春贸伐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怔揩。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工捉邢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人商膊。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓伏伐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親晕拆。 傳聞我的和親對象是個殘疾皇子藐翎,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348