GCD學(xué)習(xí)之group

GCD的group方法只有async(異步方法)即

void dispatch_group_async(dispatch_group_t group,
    dispatch_queue_t queue,
    dispatch_block_t block);

使用group要傳2個(gè)參數(shù) group、queue,其中g(shù)roup使用

//創(chuàng)建group
dispatch_group_t group = dispatch_group_create();

queue我們可以使用以下幾種方式

dispatch_queue_t queue = dispatch_get_main_queue()
//或者 
queue = dispatch_get_global_queue(0, 0);
//或者 并行隊(duì)列
queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_CONCURRENT);
//或者串行隊(duì)列
queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_SERIAL);

這里主要區(qū)分串行和并行的方式

- (void)doSomething:(void (^)())handler {
    if (handler) {
        sleep(2);
        handler();
    }
}
//異步串行g(shù)roup
- (void)groupAsyncSerialTest {
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_SERIAL);
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, queue, ^{
        [self doSomething:^() {
            NSLog(@"任務(wù)一");
        }];
    });
    dispatch_group_async(group, queue, ^{
        [self doSomething:^() {
            NSLog(@"任務(wù)二");
        }];
    });
    dispatch_group_async(group, queue, ^{
        [self doSomething:^() {
            NSLog(@"任務(wù)三");
        }];
    });
    dispatch_group_notify(group, queue, ^{
        NSLog(@"前面的任務(wù)已完成");
    });
}

結(jié)果


串行隊(duì)列打印結(jié)果

值得注意的是按照順序每2s打印一次

串行隊(duì)列的情況如下:

//異步并行
- (void)groupAsyncConcurrentTest {
    //創(chuàng)建并行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_CONCURRENT);
    queue = dispatch_get_global_queue(0, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        [self doSomething:^() {
            NSLog(@"任務(wù)一");
        }];
    });
    dispatch_group_async(group, queue, ^{
        [self doSomething:^() {
            NSLog(@"任務(wù)二");
        }];
    });
    dispatch_group_async(group, queue, ^{
        [self doSomething:^() {
            NSLog(@"任務(wù)三");
        }];
    });
    dispatch_group_notify(group, queue, ^{
        NSLog(@"前面的任務(wù)已完成");
    });
}

結(jié)果如下

并行打印結(jié)果

多次試驗(yàn)總結(jié)的結(jié)果是任務(wù)完成先后順序不定,前面的任務(wù)都完成后才會(huì)執(zhí)行notify中的任務(wù)


當(dāng)然以上的情況不適用于網(wǎng)絡(luò)請求
網(wǎng)絡(luò)請求使用group時(shí)需要注意

dispatch_group_enter(group);
dispatch_group_leave(group);

搭配使用
下面是沒有搭配使用的情況

//異步并行
- (void)groupAsyncConcurrentTest {
    //創(chuàng)建并行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_CONCURRENT);
    queue = dispatch_get_global_queue(0, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        [[CMAppRequest sharedInstance] guideMessage:^() {
           NSLog(@"任務(wù)一");
        }];
    });
    dispatch_group_async(group, queue, ^{
        [[CMAppRequest sharedInstance] guideMessage:^() {
            NSLog(@"任務(wù)二");
        }];
    });
    dispatch_group_async(group, queue, ^{
        [[CMAppRequest sharedInstance] guideMessage:^() {
            NSLog(@"任務(wù)三");
        }];
    });
    dispatch_group_notify(group, queue, ^{
        NSLog(@"前面的任務(wù)已完成");
    });
}

結(jié)果如下


網(wǎng)絡(luò)請求打印結(jié)果

你會(huì)發(fā)現(xiàn)notify不起作用了,這時(shí)候就要用到enter、leave了
修改代碼如下:

//異步并行
- (void)groupAsyncConcurrentTest {
    //創(chuàng)建并行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.sccc", DISPATCH_QUEUE_CONCURRENT);
    queue = dispatch_get_global_queue(0, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_enter(group);
    [[CMAppRequest sharedInstance] guideMessage:^() {
           dispatch_group_leave(group);
           NSLog(@"任務(wù)一");
    }];
    dispatch_group_enter(group);
    [[CMAppRequest sharedInstance] guideMessage:^() {
            dispatch_group_leave(group);
            NSLog(@"任務(wù)二");
    }];
    dispatch_group_enter(group);
    [[CMAppRequest sharedInstance] guideMessage:^() {
            dispatch_group_leave(group);
            NSLog(@"任務(wù)三");
    }];
    dispatch_group_notify(group, queue, ^{
        NSLog(@"前面的任務(wù)已完成");
    });
}

//考慮到請求是異步隊(duì)列,不在需要使用dispatch_group_async

結(jié)果如下:


這就正常了,網(wǎng)絡(luò)請求的就不在做串行和并行的測試了,以上網(wǎng)絡(luò)請求部分使用的是串行隊(duì)列,串行的打印結(jié)果只和網(wǎng)絡(luò)請求的返回順序有關(guān)。

  • 最后特別需要注意,enter和leave一定要成對出現(xiàn);否則如實(shí)enter多了,notify里的任務(wù)就會(huì)永遠(yuǎn)執(zhí)行不了,若是levae多了則會(huì)照成crash

當(dāng)然這只是group的一部分還有dispatch_group_wait等功能沒有一一實(shí)現(xiàn),以上內(nèi)容只代表個(gè)人觀點(diǎn),如有問題歡迎指正,謝謝~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 GCD 術(shù)語 1.1 Serial vs. Concurrent 串行 vs. 并發(fā) 概念:該術(shù)語描述執(zhí)行當(dāng)前...
    NinthDay閱讀 4,119評論 2 38
  • 2017-07-28iOS開發(fā) 導(dǎo)語:在iOS中,多線程方案有四種:pthread、NSThread、NSOper...
    C9090閱讀 432評論 0 1
  • 在這兩部分的系列中,第一個(gè)部分的將解釋 GCD 是做什么的,并從許多基本的 GCD 函數(shù)中找出幾個(gè)來展示。在第二部...
    透支未來閱讀 405評論 0 1
  • 學(xué)習(xí)多線程,轉(zhuǎn)載兩篇大神的帖子,留著以后回顧!第一篇:關(guān)于iOS多線程,你看我就夠了 第二篇:GCD使用經(jīng)驗(yàn)與技巧...
    John_LS閱讀 723評論 0 3
  • 四圣諦:苦集滅道 五蘊(yùn) 色蘊(yùn):包括自身的眼、耳、鼻、舌、身等五根,以及反映自身而起感受作用的色、聲、香、味、觸的五...
    monchhichi1005閱讀 515評論 0 0

友情鏈接更多精彩內(nèi)容