GCD-隊列組

1.隊列組的基本概念

1.隊列組(dispatch_group_t):用來管理隊列中任務的執(zhí)行列吼。
2.隊列組的使用步驟:

  • 1.創(chuàng)建隊列組
  • 2.創(chuàng)建隊列
  • 3.使用隊列組異步函數(shù)(dispatch_group_async)封裝任務,把任務提交到隊列中
  • 4.監(jiān)聽任務的完成情況(dispatch_group_notify)

2.隊列組的基本使用

放入隊列組的隊列可以是多個隊列宏邮,可以是串行隊列或者并發(fā)隊列。
加入同一個串行隊列撕贞,則加入的任務會在同一個子線程按順序執(zhí)行,隊列組的監(jiān)聽沒有實際意義,直接把任務加到這個串行隊列即可靡挥。

dispatch_queue_t queue = dispatch_queue_create("queue_test", DISPATCH_QUEUE_SERIAL);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"任務1——準備休眠2秒,%@",[NSThread currentThread]);
        sleep(2);
        NSLog(@"任務1——完成");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"任務2——準備休眠1秒,%@",[NSThread currentThread]);
        sleep(1);
        NSLog(@"任務2——完成");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"任務組中的任務完成");
    });
    NSLog(@"主線程結(jié)束");

打印結(jié)果:

2020-02-28 11:37:23.446839+0800 Test[20493:1346501] 主線程結(jié)束
2020-02-28 11:37:23.446901+0800 Test[20493:1346542] 任務1——準備休眠2秒,<NSThread: 0x6000037ea500>{number = 3, name = (null)}
2020-02-28 11:37:25.451652+0800 Test[20493:1346542] 任務1——完成
2020-02-28 11:37:25.451959+0800 Test[20493:1346542] 任務2——準備休眠1秒,<NSThread: 0x6000037ea500>{number = 3, name = (null)}
2020-02-28 11:37:26.455702+0800 Test[20493:1346542] 任務2——完成
2020-02-28 11:37:26.456015+0800 Test[20493:1346501] 任務組中的任務完成

把任務加入不同的串行隊列,則加入的任務會在兩個子線程并發(fā)執(zhí)行

dispatch_queue_t queue = dispatch_queue_create("queue_test", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue1 = dispatch_queue_create("queue_test1", DISPATCH_QUEUE_SERIAL);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"任務1——準備休眠2秒,%@",[NSThread currentThread]);
        sleep(2);
        NSLog(@"任務1——完成");
    });
    dispatch_group_async(group, queue1, ^{
        NSLog(@"任務2——準備休眠1秒,%@",[NSThread currentThread]);
        sleep(1);
        NSLog(@"任務2——完成");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"任務組中的任務完成");
    });
    NSLog(@"主線程結(jié)束");

打印結(jié)果:

2020-02-28 11:39:30.363815+0800 Test[20533:1349943] 主線程結(jié)束
2020-02-28 11:39:30.363881+0800 Test[20533:1349995] 任務2——準備休眠1秒,<NSThread: 0x600001c1b180>{number = 4, name = (null)}
2020-02-28 11:39:30.363901+0800 Test[20533:1349994] 任務1——準備休眠2秒,<NSThread: 0x600001c1ccc0>{number = 3, name = (null)}
2020-02-28 11:39:31.367371+0800 Test[20533:1349995] 任務2——完成
2020-02-28 11:39:32.369266+0800 Test[20533:1349994] 任務1——完成
2020-02-28 11:39:32.369610+0800 Test[20533:1349943] 任務組中的任務完成

把任務加入同一個并發(fā)隊列鸯绿,會在不同線程并發(fā)執(zhí)行跋破。

dispatch_queue_t queue = dispatch_queue_create("queue_test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"任務1——準備休眠2秒,%@",[NSThread currentThread]);
        sleep(2);
        NSLog(@"任務1——完成");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"任務2——準備休眠1秒,%@",[NSThread currentThread]);
        sleep(1);
        NSLog(@"任務2——完成");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"任務組中的任務完成");
    });
    NSLog(@"主線程結(jié)束");

打印結(jié)果:

2020-02-28 14:16:27.847481+0800 Test[21744:1447421] 主線程結(jié)束
2020-02-28 14:16:27.847552+0800 Test[21744:1447471] 任務2——準備休眠1秒,<NSThread: 0x60000265d500>{number = 4, name = (null)}
2020-02-28 14:16:27.847570+0800 Test[21744:1447472] 任務1——準備休眠2秒,<NSThread: 0x6000026560c0>{number = 3, name = (null)}
2020-02-28 14:16:28.848630+0800 Test[21744:1447471] 任務2——完成
2020-02-28 14:16:29.851477+0800 Test[21744:1447472] 任務1——完成
2020-02-28 14:16:29.851826+0800 Test[21744:1447421] 任務組中的任務完成

把任務放入不同的并發(fā)隊列,會在不同線程并發(fā)執(zhí)行

dispatch_queue_t queue = dispatch_queue_create("queue_test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t queue1 = dispatch_queue_create("queue_test1", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"任務1——準備休眠2秒,%@",[NSThread currentThread]);
        sleep(2);
        NSLog(@"任務1——完成");
    });
    dispatch_group_async(group, queue1, ^{
        NSLog(@"任務2——準備休眠1秒,%@",[NSThread currentThread]);
        sleep(1);
        NSLog(@"任務2——完成");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"任務組中的任務完成");
    });
    NSLog(@"主線程結(jié)束");

打印結(jié)果:

2020-02-28 14:17:43.878824+0800 Test[21779:1449847] 主線程結(jié)束
2020-02-28 14:17:43.878918+0800 Test[21779:1449944] 任務1——準備休眠2秒,<NSThread: 0x600003e6d900>{number = 3, name = (null)}
2020-02-28 14:17:43.878918+0800 Test[21779:1449949] 任務2——準備休眠1秒,<NSThread: 0x600003e61480>{number = 4, name = (null)}
2020-02-28 14:17:44.881581+0800 Test[21779:1449949] 任務2——完成
2020-02-28 14:17:45.882695+0800 Test[21779:1449944] 任務1——完成
2020-02-28 14:17:45.883016+0800 Test[21779:1449847] 任務組中的任務完成

總結(jié):加入隊列組的任務可以是串行隊列的瓶蝴,也可以是并發(fā)隊列的毒返。可以是同一個隊列的任務舷手,也可以是多個隊列的任務拧簸。但是如果是加入同一個串行隊列,本來就會按順序在同一個線程執(zhí)行男窟。
核心方法

  • 1.dispatch_group_create() 創(chuàng)建隊列組
  • 2.dispatch_group_async(group, queue, ^{}); 往隊列組添加任務
  • 3.dispatch_group_notify(group, dispatch_get_main_queue(), ^{}); //讓隊列組監(jiān)聽任務的完成,把監(jiān)聽任務放在添加任務前不一定有效(實驗在監(jiān)聽之后添加一萬個任務,dispatch_group_notify中的方法在中間調(diào)用)盆赤,所以dispatch_group_notify必須寫在添加完所有任務之后。

3.隊列組的dispatch_group_enter,dispatch_group_leave函數(shù)對用法

隊列組的函數(shù)對用法是目前比較少見的用法, 這個用法比較老, 好處是嚴格的控制/監(jiān)聽了每個進入隊列組的任務
使用步驟:

  • 1.創(chuàng)建隊列組
  • 2.創(chuàng)建隊列歉眷,使用異步函數(shù),如果使用同步函數(shù)牺六,添加的方法會按順序執(zhí)行,沒有實際意義姥芥。
  • 3.開啟隊列組兔乞,通過函數(shù)添加任務
    注意點:在通過函數(shù)添加任務之前必須調(diào)用dispatch_group_enter(group);,用來確定往group這個隊列組添加任務凉唐,任務代碼結(jié)束后必須調(diào)用dispatch_group_leave(group);用來確保已經(jīng)離開隊列組庸追,否則不會調(diào)用dispatch_group_notify這個監(jiān)聽方法。
dispatch_queue_t queue = dispatch_queue_create("queue test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"任務1——準備休眠2秒,%@",[NSThread currentThread]);
        sleep(2);
        NSLog(@"任務1——完成");
        dispatch_group_leave(group);
    });
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"任務2——準備休眠1秒,%@",[NSThread currentThread]);
        sleep(1);
        NSLog(@"任務2——完成");
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"任務組中的任務完成");
    });

打印結(jié)果:

2020-02-28 14:44:05.307563+0800 Test[22253:1494879] 任務1——準備休眠2秒,<NSThread: 0x60000374a240>{number = 3, name = (null)}
2020-02-28 14:44:05.307735+0800 Test[22253:1494889] 任務2——準備休眠1秒,<NSThread: 0x600003744880>{number = 4, name = (null)}
2020-02-28 14:44:06.311042+0800 Test[22253:1494889] 任務2——完成
2020-02-28 14:44:07.311707+0800 Test[22253:1494879] 任務1——完成
2020-02-28 14:44:07.312074+0800 Test[22253:1494785] 任務組中的任務完成

對于加入隊列組中的隊列是串行還是并行台囱,同一個隊列還是多個隊列的結(jié)果淡溯,和基本用法中相同

4. dispatch_group_wait函數(shù)

dispatch_group_wait能阻塞線程,判斷隊列組的任務能否在規(guī)定時間內(nèi)完成簿训,若在規(guī)定時間內(nèi)完成會返回0咱娶,否則是非0值。然后在到達規(guī)定時間后不管隊列組內(nèi)任務是否完成强品,往下執(zhí)行代碼膘侮。
該函數(shù)和dispatch_group_notify函數(shù)不沖突。

    dispatch_queue_t queue = dispatch_queue_create("queue_test", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t queue1 = dispatch_queue_create("queue_test1", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"任務1——準備休眠5秒,%@",[NSThread currentThread]);
        sleep(5);
        NSLog(@"任務1——完成");
    });
    dispatch_group_async(group, queue1, ^{
        NSLog(@"任務2——準備休眠1秒,%@",[NSThread currentThread]);
        sleep(1);
        NSLog(@"任務2——完成");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"任務組中的任務完成");
    });
    // 同步執(zhí)行的榛,等待隊列組time的時間后執(zhí)行后面的代碼琼了,如果隊列組中的任務都完成了,就返回0,如果沒完成雕薪,就返回非0值
    dispatch_time_t timer = dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC);

    // 等待tiemr秒的時間昧诱,不管隊列中任務是否完成,都繼續(xù)往下執(zhí)行所袁,如果該時間內(nèi)任務完成了就返回0盏档,否則是非零值
    long n = dispatch_group_wait(group, timer);
    NSLog(@"%ld", n);
    NSLog(@"主線程結(jié)束");

打印結(jié)果

2020-02-28 15:03:56.876353+0800 Test[22672:1529852] 任務2——準備休眠1秒,<NSThread: 0x6000030f8300>{number = 4, name = (null)}
2020-02-28 15:03:56.876353+0800 Test[22672:1529851] 任務1——準備休眠5秒,<NSThread: 0x6000030fc380>{number = 3, name = (null)}
2020-02-28 15:03:57.876948+0800 Test[22672:1529852] 任務2——完成
2020-02-28 15:03:58.877405+0800 Test[22672:1529113] 49
2020-02-28 15:03:58.877693+0800 Test[22672:1529113] 主線程結(jié)束
2020-02-28 15:04:01.880121+0800 Test[22672:1529851] 任務1——完成
2020-02-28 15:04:01.880516+0800 Test[22672:1529113] 任務組中的任務完成

由上述結(jié)果可以知道:
在執(zhí)行過dispatch_group_wait函數(shù)后,主線程不再往下執(zhí)行燥爷,主線程等待2秒后繼續(xù)執(zhí)行代碼蜈亩,此時任務1并沒有完成,所以dispatch_group_wait函數(shù)可以阻斷線程一定時間前翎。
在任務1完成后勺拣,dispatch_group_notify繼續(xù)執(zhí)行里面的代碼,所以說明dispatch_group_notify和dispatch_group_wait不沖突鱼填。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末药有,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子苹丸,更是在濱河造成了極大的恐慌愤惰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赘理,死亡現(xiàn)場離奇詭異宦言,居然都是意外死亡,警方通過查閱死者的電腦和手機商模,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門奠旺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人施流,你說我怎么就攤上這事响疚。” “怎么了瞪醋?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵忿晕,是天一觀的道長。 經(jīng)常有香客問我银受,道長践盼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任宾巍,我火速辦了婚禮咕幻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘顶霞。我一直安慰自己肄程,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著绷耍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鲜侥。 梳的紋絲不亂的頭發(fā)上褂始,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音描函,去河邊找鬼崎苗。 笑死,一個胖子當著我的面吹牛舀寓,可吹牛的內(nèi)容都是我干的胆数。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼互墓,長吁一口氣:“原來是場噩夢啊……” “哼必尼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起篡撵,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤判莉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后育谬,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體券盅,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年膛檀,在試婚紗的時候發(fā)現(xiàn)自己被綠了锰镀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡咖刃,死狀恐怖泳炉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嚎杨,我是刑警寧澤胡桃,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站磕潮,受9級特大地震影響翠胰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜自脯,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一之景、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧膏潮,春花似錦锻狗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽油额。三九已至,卻和暖如春刻帚,著一層夾襖步出監(jiān)牢的瞬間潦嘶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工崇众, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留掂僵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓顷歌,卻偏偏與公主長得像锰蓬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子眯漩,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353