iOS 多線程-GCD隊列組

iOS 多線程-GCD任務+隊列.

在實際的開發中,對於多線程的使用是多種多樣的,因爲需求的不同,處理邏輯也不同。
現在有兩個耗時操作A和B,現在需要A和B都異步執行,當A和B都執行完成後再執行C。
這樣的操作邏輯很常見,例如:一個界面需要展示兩個接口請求的數據,需要兩個接口全部請求完成才能刷新視圖,展示數據。
對於這樣的操作邏輯,對於這樣的操作要求,我們可以使用隊列組來完成。

隊列組的使用

隊列組的使用我分爲3種方式:
1、通知方式:dispatch_group_notify
2、等待方式(堵塞方式):dispatch_group_wait
3、進入走出方式:dispatch_group_enter、dispatch_group_leave

無論是哪一種方式,都需要先去創建隊列組、創建隊列和創建任務。
1、創建隊列組:

	//創建隊列組
    dispatch_group_t group = dispatch_group_create();
    //獲取全局並行隊列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

通知方式:dispatch_group_notify

- (void)queueGroupNotify{
    //創建隊列組
    dispatch_group_t group = dispatch_group_create();
    //獲取全局並行隊列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    //創建異步任務
    dispatch_group_async(group, queue, ^{
        //任務1
        for (int i = 0; i < 3; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"任務1的執行=====%d", i);
        }
    });
    
    //創建異步任務
    dispatch_group_async(group, queue, ^{
        //任務2
        for (int i = 0; i < 3; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"任務2的執行=====%d", i);
        }
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        //任務3
        for (int i = 0; i < 3; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"回到主線程執行=====%d", i);
        }
    });
}

打印結果:
2020-03-18 16:11:26.065895+0800 GCDdemo[87505:1358550] 任務2的執行=====0
2020-03-18 16:11:26.065937+0800 GCDdemo[87505:1358551] 任務1的執行=====0
2020-03-18 16:11:28.071042+0800 GCDdemo[87505:1358550] 任務2的執行=====1
2020-03-18 16:11:28.071042+0800 GCDdemo[87505:1358551] 任務1的執行=====1
2020-03-18 16:11:30.075650+0800 GCDdemo[87505:1358551] 任務1的執行=====2
2020-03-18 16:11:30.075663+0800 GCDdemo[87505:1358550] 任務2的執行=====2
2020-03-18 16:11:32.077253+0800 GCDdemo[87505:1358470] 回到主線程執行=====0
2020-03-18 16:11:34.078721+0800 GCDdemo[87505:1358470] 回到主線程執行=====1
2020-03-18 16:11:36.079946+0800 GCDdemo[87505:1358470] 回到主線程執行=====2

從上面的打印結果可以看出:任務1和任務2是異步執行的,並且在任務1和任務2執行完成後纔回到主線程執行。

等待方式(堵塞方式):dispatch_group_wait

- (void)queueGroupWait{
    //創建隊列組
    dispatch_group_t group = dispatch_group_create();
    //獲取全局並行隊列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    //創建異步任務
    dispatch_group_async(group, queue, ^{
        //任務1
        for (int i = 0; i < 3; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"任務1的執行=====%d", i);
        }
    });
    
    //創建異步任務
    dispatch_group_async(group, queue, ^{
        //任務2
        for (int i = 0; i < 3; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"任務2的執行=====%d", i);
        }
    });
    
    /**
     DISPATCH_TIME_NOW (0ull)            立即執行任務3,不等待
     DISPATCH_TIME_FOREVER (~0ull)  等待上面兩個任務執行完成在執行任務3
     */
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    //任務3
    for (int i = 0; i < 3; i++) {
        [NSThread sleepForTimeInterval:2];
        NSLog(@"回到主線程執行=====%d", i);
    }
}

打印結果:
2020-03-18 16:21:22.095224+0800 GCDdemo[87837:1367632] 任務2的執行=====0
2020-03-18 16:21:22.095228+0800 GCDdemo[87837:1367630] 任務1的執行=====0
2020-03-18 16:21:24.099197+0800 GCDdemo[87837:1367632] 任務2的執行=====1
2020-03-18 16:21:24.099197+0800 GCDdemo[87837:1367630] 任務1的執行=====1
2020-03-18 16:21:26.101743+0800 GCDdemo[87837:1367630] 任務1的執行=====2
2020-03-18 16:21:26.101750+0800 GCDdemo[87837:1367632] 任務2的執行=====2
2020-03-18 16:21:28.103304+0800 GCDdemo[87837:1367440] 回到主線程執行=====0
2020-03-18 16:21:30.104813+0800 GCDdemo[87837:1367440] 回到主線程執行=====1
2020-03-18 16:21:32.106304+0800 GCDdemo[87837:1367440] 回到主線程執行=====2

從上面的打印結果可以看出:任務1和任務2是異步執行的,並且在任務1和任務2執行完成後纔回到主線程執行。

進入走出方式:dispatch_group_enter、dispatch_group_leave

注意:dispatch_group_enter和dispatch_group_leave必須成對出現,這個組合等同於dispatch_group_async

- (void)queueGroupEnterLeace{
    //創建隊列組
    dispatch_group_t group = dispatch_group_create();
    //獲取全局並行隊列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    //進組
    dispatch_group_enter(group);
    //創建異步任務,這裏不需要使用dispatch_group_async創建任務,使用dispatch_async
    dispatch_async(queue, ^{
        //任務1
        for (int i = 0; i < 3; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"任務1的執行=====%d", i);
        }
        //出組
        dispatch_group_leave(group);
    });
    
    //進組
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        //任務2
        for (int i = 0; i < 3; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"任務2的執行=====%d", i);
        }
        //出組
        dispatch_group_leave(group);
    });
    
    //通知
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        //任務3
        for (int i = 0; i < 3; i++) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"回到主線程執行=====%d", i);
        }
    });
}

打印結果:
2020-03-18 16:27:18.437480+0800 GCDdemo[88018:1373486] 任務2的執行=====0
2020-03-18 16:27:18.437479+0800 GCDdemo[88018:1373485] 任務1的執行=====0
2020-03-18 16:27:20.442395+0800 GCDdemo[88018:1373486] 任務2的執行=====1
2020-03-18 16:27:20.442395+0800 GCDdemo[88018:1373485] 任務1的執行=====1
2020-03-18 16:27:22.447306+0800 GCDdemo[88018:1373486] 任務2的執行=====2
2020-03-18 16:27:22.447331+0800 GCDdemo[88018:1373485] 任務1的執行=====2
2020-03-18 16:27:24.448925+0800 GCDdemo[88018:1373403] 回到主線程執行=====0
2020-03-18 16:27:26.450413+0800 GCDdemo[88018:1373403] 回到主線程執行=====1
2020-03-18 16:27:28.451925+0800 GCDdemo[88018:1373403] 回到主線程執行=====2

從上面的打印結果可以看出:任務1和任務2是異步執行的,並且在任務1和任務2執行完成後纔回到主線程執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章