iOS多線程 GCD使用

各種方法

  1. 獲取主線程隊列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
  1. 獲取global子線程隊列
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

關(guān)于子線程隊列priority钞螟,執(zhí)行完High悔醋,再執(zhí)行Default拢锹,然后是Low谣妻,最后是Backgound。

  1. 創(chuàng)建自定義隊列
dispatch_queue_t customQueue = dispatch_queue_create("com.uzai.testQueue", DISPATCH_QUEUE_CONCURRENT);

創(chuàng)建隊列卒稳,serial串行執(zhí)行蹋半,concurrent并行執(zhí)行

  1. 異步執(zhí)行
dispatch_async(customQueue, ^{
    NSLog(@"custom serial queue %@",[NSThread currentThread]);
});
  1. 同步執(zhí)行
dispatch_sync(customQueue, ^{
    NSLog(@"custom serial queue %@",[NSThread currentThread]);
});

異步執(zhí)行串行隊列,同一子線程串行執(zhí)行
異步執(zhí)行并行隊列充坑,多個子線程并行執(zhí)行
同步執(zhí)行串行隊列减江,主線程串行執(zhí)行
同步執(zhí)行并行隊列染突,主線程串行執(zhí)行

  1. 按次數(shù)執(zhí)行block

按照指定次數(shù)將 block 添加到指定的隊列當(dāng)中,dispatch_apply函數(shù)會等待全部處理結(jié)束辈灼。

dispatch_queue_t asyncQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSArray *wordsArray = @[@"GCD",@"NSOperations",@"NSOperationQueues",@"algorithms"];
dispatch_apply(wordsArray.count, asyncQueue, ^(size_t currentIndex) {
    NSLog(@"current size -> %@",wordsArray[currentIndex]);
});
NSLog(@"all applies are done");
  1. 創(chuàng)建單例
+ (instancetype)shareInstance {
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}
  1. dispatch_group
  • 使用dispatch_group_async在多個異步任務(wù)完成后份企,再執(zhí)行dispatch_group_notify中的任務(wù)。
dispatch_queue_t current1 = dispatch_queue_create("current1", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, current1, ^{
    sleep(3);
    NSLog(@"current 1 finish %@",[NSThread currentThread]);
});

dispatch_group_async(group, current1, ^{
    sleep(3);
    NSLog(@"current 2 finish %@",[NSThread currentThread]);
});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"all finish");
});

//output
//2017-12-07 15:57:59.207 iOSInterviewProblems[64337:3876851] current 1 finish <NSThread: 0x60800026f6c0>{number = 9, name = (null)}
//2017-12-07 15:58:02.282 iOSInterviewProblems[64337:3945895] current 2 finish <NSThread: 0x600000270800>{number = 12, name = (null)}
//2017-12-07 15:58:02.282 iOSInterviewProblems[64337:3875012] all finish
  • 使用 dispatch_group_enter巡莹,dispatch_group_leave 獲取多個異步線程執(zhí)行完成時候司志。
  1. dispatch_group_enter 在任務(wù)開始執(zhí)行時調(diào)用
  2. dispatch_group_leave 在任務(wù)完成時調(diào)用
dispatch_group_t downloadGroup = dispatch_group_create();
dispatch_queue_t downloadQueue = dispatch_queue_create("com.uzai.download", DISPATCH_QUEUE_CONCURRENT);

for (int i = 0; i < 6; i++) {
    dispatch_group_enter(downloadGroup);
    dispatch_async(downloadQueue, ^{
        NSLog(@"now downloading");
        sleep(i);
        dispatch_group_leave(downloadGroup);
        NSLog(@"downloaded");
    });
}

dispatch_group_notify(downloadGroup, dispatch_get_main_queue(), ^{
    NSLog(@"all download done");
});

//output
//    2017-12-07 17:06:24.765 iOSInterviewProblems[65166:3996044] now downloading
//    2017-12-07 17:06:24.765 iOSInterviewProblems[65166:3995991] now downloading
//    2017-12-07 17:06:24.765 iOSInterviewProblems[65166:3995994] now downloading
//    2017-12-07 17:06:24.765 iOSInterviewProblems[65166:3996044] downloaded
//    2017-12-07 17:06:24.765 iOSInterviewProblems[65166:3996047] now downloading
//    2017-12-07 17:06:24.766 iOSInterviewProblems[65166:3996044] now downloading
//    2017-12-07 17:06:24.766 iOSInterviewProblems[65166:3996048] now downloading
//    2017-12-07 17:06:25.840 iOSInterviewProblems[65166:3995991] downloaded
//    2017-12-07 17:06:26.766 iOSInterviewProblems[65166:3995994] downloaded
//    2017-12-07 17:06:27.840 iOSInterviewProblems[65166:3996047] downloaded
//    2017-12-07 17:06:28.766 iOSInterviewProblems[65166:3996044] downloaded
//    2017-12-07 17:06:29.767 iOSInterviewProblems[65166:3996048] downloaded
//    2017-12-07 17:06:29.767 iOSInterviewProblems[65166:3995950] all download done
  1. dispatch_sources

GCD提供一系列的dispatch sources,用來監(jiān)控活動的狀況(底層系統(tǒng)活動降宅,例如Unix 信號骂远,VFS 節(jié)點 等等)。并且在上述活動發(fā)生的時候腰根,執(zhí)行提交到隊列的事務(wù)激才。

  • 創(chuàng)建GCDTimer

    • gcd timer帶有兩個參數(shù),interval代表的是觸發(fā)時機(jī)额嘿,leeway代表的是允許的誤差瘸恼。例如設(shè)置interval = 1,leeway = 1册养。代表著1秒觸發(fā)东帅,可以有1秒的偏差。
    • timer無法自動釋放捕儒,需要通過dispatch_source_cancel進(jìn)行釋放冰啃。
//創(chuàng)建并啟動timer
if (self.timerSource == nil) {
    self.timerCountDown = 0;
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    self.timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_source_set_timer(self.timerSource, dispatch_walltime(NULL, 0), 1 * NSEC_PER_SEC, 1 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(self.timerSource, ^{
        self.timerCountDown++;
        NSLog(@"printting now -> %d",self.timerCountDown);
    });
    dispatch_resume(self.timerSource);
}

//暫停timer
if (self.timerSource) {
    dispatch_suspend(self.timerSource);
}

//取消掉timer
if (self.timerSource) {
    dispatch_source_cancel(self.timerSource);
}

示例參見 github Demo

注意事項

  • dispatch_sync 使用
    該方法直到block執(zhí)行完畢才會返回執(zhí)行下一個任務(wù)邓夕。在當(dāng)前隊列調(diào)用會造成死鎖刘莹。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市焚刚,隨后出現(xiàn)的幾起案子点弯,更是在濱河造成了極大的恐慌,老刑警劉巖矿咕,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抢肛,死亡現(xiàn)場離奇詭異,居然都是意外死亡碳柱,警方通過查閱死者的電腦和手機(jī)捡絮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來莲镣,“玉大人福稳,你說我怎么就攤上這事∪鹞辏” “怎么了的圆?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵鼓拧,是天一觀的道長。 經(jīng)常有香客問我越妈,道長季俩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任梅掠,我火速辦了婚禮酌住,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瓤檐。我一直安慰自己赂韵,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布挠蛉。 她就那樣靜靜地躺著祭示,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谴古。 梳的紋絲不亂的頭發(fā)上质涛,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機(jī)與錄音掰担,去河邊找鬼汇陆。 笑死,一個胖子當(dāng)著我的面吹牛带饱,可吹牛的內(nèi)容都是我干的毡代。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼勺疼,長吁一口氣:“原來是場噩夢啊……” “哼教寂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起执庐,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤酪耕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后轨淌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迂烁,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年递鹉,在試婚紗的時候發(fā)現(xiàn)自己被綠了盟步。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡躏结,死狀恐怖却盘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤谷炸,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布北专,位于F島的核電站,受9級特大地震影響旬陡,放射性物質(zhì)發(fā)生泄漏拓颓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一描孟、第九天 我趴在偏房一處隱蔽的房頂上張望驶睦。 院中可真熱鬧,春花似錦匿醒、人聲如沸场航。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽溉痢。三九已至,卻和暖如春憋他,著一層夾襖步出監(jiān)牢的瞬間孩饼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工竹挡, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留镀娶,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓揪罕,卻偏偏與公主長得像梯码,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子好啰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359

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