GCD 學(xué)習(xí)小結(jié)

概念


串行隊列、并行隊列

  • 串行隊列蓝牲,是指同一時間內(nèi)趟脂,隊列內(nèi)只有一個任務(wù)在執(zhí)行。
  • 并行隊列例衍,是指同一時間內(nèi)散怖,隊列內(nèi)有多個任務(wù)同時執(zhí)行。

同步執(zhí)行肄渗、異步執(zhí)行

  • 同步執(zhí)行镇眷,是指在完成預(yù)定的任務(wù)后才返回,在任務(wù)執(zhí)行時會阻塞當(dāng)前線程翎嫡。
  • 異步執(zhí)行欠动,則是指任務(wù)提交后,任務(wù)會在另外的線程中運行惑申,當(dāng)前線程并不會等待任務(wù)的完成具伍,所以異步任務(wù)不會阻塞當(dāng)前線程。

用法


隊列的創(chuàng)建和獲取

系統(tǒng)提供了主線程隊列和全局隊列供用戶調(diào)用使用圈驼,主線程隊列是串行隊列人芽,全局隊列則是并行隊列。獲取系統(tǒng)提供的隊列绩脆,方法如下:

// 獲取主線程隊列
dispatch_queue_t mainQueue = dispatch_get_main_queue();

// 獲取全局隊列
dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

系統(tǒng)提供了四種優(yōu)先級的全局隊列萤厅,通過dispatch_get_global_queue的第一個參數(shù)區(qū)分橄抹,四種優(yōu)先級類型分別為:

DISPATCH_QUEUE_PRIORITY_HIGH // 高優(yōu)先級
DISPATCH_QUEUE_PRIORITY_DEFAULT // 默認優(yōu)先級
DISPATCH_QUEUE_PRIORITY_LOW // 低優(yōu)先級
DISPATCH_QUEUE_PRIORITY_BACKGROUND // 后臺

優(yōu)先級高的隊列中的任務(wù),會比優(yōu)先級低的隊列中的任務(wù)先執(zhí)行惕味。后臺級別的隊列優(yōu)先級最低楼誓,只有在其它隊列的任務(wù)執(zhí)行完或CPU空閑時,才會執(zhí)行后臺級別隊列中的任務(wù)名挥。

另外疟羹,用戶可以創(chuàng)建自己的隊列,創(chuàng)建隊列的方法如下:

dispatch_queue_t myQueue = dispatch_queue_create("com.example.myqueue", DISPATCH_QUEUE_CONCURRENT);

其中第二個參數(shù)禀倔,決定創(chuàng)建的是串行隊列還是并行隊列榄融。

使用隊列執(zhí)行任務(wù)

使用隊列執(zhí)行任務(wù),分同步和異步兩種救湖,一般情況下剃袍,異步的比較常用,使用方法如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // do something...
});

延遲隊列中任務(wù)的執(zhí)行

有時候我們在提交任務(wù)后捎谨,并不想任務(wù)馬上被執(zhí)行,而是需要等待一段時間后再開始執(zhí)行憔维,這時候可以使用dispatch_after的方法涛救。

// 延遲3秒執(zhí)行
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
dispatch_after(delay, dispatch_get_main_queue(), ^{
    NSLog(@"Run delay 3 seconds...");
});

任務(wù)組的使用

實際開發(fā)中會遇到這樣一種情況,需要等待多個任務(wù)都完成(任務(wù)完成順序不分先后)后业扒,再進行某些操作检吆,比如網(wǎng)絡(luò)資源的分段下載,拆分到N個子任務(wù)中進行程储,子任務(wù)都下載完后蹭沛,再合并成一個完整的資源。

dispatch_group_t myGroup = dispatch_group_create();
dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_async(myGroup, defaultQueue, ^{
    NSLog(@"Download task 1...");
});
dispatch_group_async(myGroup, defaultQueue, ^{
    NSLog(@"Download task 2...");
});
dispatch_group_async(myGroup, defaultQueue, ^{
    NSLog(@"Download task 3...");
});

dispatch_group_notify(myGroup, defaultQueue, ^{
    NSLog(@"All Download task finish, combine resources!");
});

同步任務(wù)的等待

同步任務(wù)之間章鲤,有依賴的關(guān)系摊灭,后面的任務(wù)需要依賴前面任務(wù)的返回結(jié)果,或是需要等待前面的任務(wù)執(zhí)行完才可進行败徊,此時可以使用dipatch_barrier_async帚呼。

dispatch_queue_t myQueue = dispatch_queue_create("com.example.myqueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue, ^{
    [NSThread sleepForTimeInterval:2];
    NSLog(@"===> 1");
});
dispatch_async(myQueue, ^{
    [NSThread sleepForTimeInterval:4];
    NSLog(@"===> 2");
});
dispatch_barrier_async(myQueue, ^{
    NSLog(@"===> 3");
    [NSThread sleepForTimeInterval:4];
});
dispatch_async(myQueue, ^{
    [NSThread sleepForTimeInterval:1];
    NSLog(@"===> 4");
});

這段代碼,會按順序輸出1皱蹦,2煤杀,3,4沪哺。dispatch_barrier_async會等待比它先提交的任務(wù)返回后沈自,再執(zhí)行自己提交的任務(wù),而在它后面提交的任務(wù)辜妓,則需要等待它返回后才能執(zhí)行枯途。

異步任務(wù)的等待

異步任務(wù)之間的依賴忌怎,則需要使用信號量。示例代碼如下:

dispatch_semaphore_t lock;

- (void)executeTaskOne {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"Task one start...");
        sleep(5);
        NSLog(@"Task one finish!");
        
        // 此處信號量的值+1
        dispatch_semaphore_signal(lock); 
    });
}

- (void)executeTaskTwo {
    // 此處信號量的值-1柔袁,如果-1后信號量的值<0呆躲,則一直等待,直到信號量的值>=0時再執(zhí)行
    dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"Task two start...");
        sleep(3);
        NSLog(@"Task two finish!");
    });
}

- (void)executeCombinedTask {
    lock = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self executeTaskOne];
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self executeTaskTwo];
    });
}

此段代碼執(zhí)行捶索,會依次輸出

Task one start...
Task one finish!
Task two start...
Task two finish!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末插掂,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子腥例,更是在濱河造成了極大的恐慌辅甥,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燎竖,死亡現(xiàn)場離奇詭異璃弄,居然都是意外死亡,警方通過查閱死者的電腦和手機构回,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門夏块,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人纤掸,你說我怎么就攤上這事脐供。” “怎么了借跪?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵政己,是天一觀的道長。 經(jīng)常有香客問我掏愁,道長歇由,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任果港,我火速辦了婚禮沦泌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辛掠。我一直安慰自己赦肃,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布公浪。 她就那樣靜靜地躺著他宛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪欠气。 梳的紋絲不亂的頭發(fā)上厅各,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音预柒,去河邊找鬼队塘。 笑死袁梗,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的憔古。 我是一名探鬼主播遮怜,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鸿市!你這毒婦竟也來了锯梁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤焰情,失蹤者是張志新(化名)和其女友劉穎陌凳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體内舟,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡合敦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了验游。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片充岛。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖耕蝉,靈堂內(nèi)的尸體忽然破棺而出崔梗,到底是詐尸還是另有隱情,我是刑警寧澤赔硫,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站盐肃,受9級特大地震影響爪膊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砸王,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一推盛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谦铃,春花似錦耘成、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘹朗,卻和暖如春师妙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背屹培。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工默穴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怔檩,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓蓄诽,卻偏偏與公主長得像薛训,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子仑氛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,612評論 2 350

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