GCD dispatch_group的理解及使用

1、關于dispatch_group
把一組任務提交到隊列中,這些隊列可以不相關,然后監聽這組任務完成的事件。
2、最常見的幾個方法:

1、dispatch_group_create創建一個調度任務組
 2、dispatch_group_async 把一個任務異步提交到任務組里
 3、dispatch_group_enter/dispatch_group_leave 這種方式用在不使用dispatch_group_async來提交任務,且必須配合使用
 4、dispatch_group_notify 用來監聽任務組事件的執行完畢
 5、dispatch_group_wait 設置等待時間,在等待時間結束后,如果還沒有執行完任務組,則返回。返回0代表執行成功,非0則執行失敗

3、實際使用場景

場景1:
現在有4個任務,任務1、任務2、任務3、任務4. 任務3必須在任務2之后,任務4必須在前3個任務都執行完成后,才能執行,并且需要在主線程更新UI。
思路分析:
任務3必須在任務2之后,所以這兩個必須串行執行,同時,任務2和3整體可以和任務1并行執行,最后,任務4只能等待前3個任務全部執行完成,才能執行。這里就可以用group快速實現場景需求。

- (void)dispatchGroup {
    
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t serialQueue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_SERIAL);
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, globalQueue, ^{
        NSLog(@"run task 1");
    });
    
    dispatch_group_async(group, serialQueue, ^{
         NSLog(@"run task 2");
    });
    
    dispatch_group_async(group, serialQueue, ^{
        NSLog(@"run task 3");
    });
    
    dispatch_group_async(group, dispatch_get_main_queue(), ^{
        NSLog(@"run task 4");
    });
}

執行結果:
image

總結: 1和(2、3)是并行執行關系,2、3是串行執行關系,且3肯定在2之后,而4在(1、2、3)全部完成之后才會執行。

4、dispatch_group_enter(group)、dispatch_group_leave(group) 何時使用
這兩個方法可以:手動管理group關聯的block的運行狀態(或計數),并且使用時必須保證進入和退出group次數匹配。
所以:A和B兩種使用方式可以講是等價的

A)
 dispatch_group_async(group, queue, ^{
   // ....
 });
 
 B)
 dispatch_group_enter(group);
 dispatch_async(queue, ^{
   // ....
   dispatch_group_leave(group);
 });

應用場景:有3個異步請求任務,任務1、2、3,在3個任務全部完成之后,需要執行任務4,用以顯示界面數據。
用 dispatch_group_enter、 dispatch_group_leave 實現:

-(void)disGroupEnterAndLeave{
    dispatch_queue_t globalQuene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    
    //任務1
    dispatch_group_enter(group);
    dispatch_async(globalQuene, ^{
        NSLog(@"run task 1");
        sleep(1);
        dispatch_group_leave(group);
    });
    
    //任務2
    dispatch_group_enter(group);
    dispatch_async(globalQuene, ^{
        NSLog(@"run task 2");
        sleep(2);
        dispatch_group_leave(group);
    });
    
    //任務3
    dispatch_group_enter(group);
    dispatch_async(globalQuene, ^{
        NSLog(@"run task 3");
        sleep(3);
        dispatch_group_leave(group);
    });
    
    //一直等待完成
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    
    //任務3
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"run task 4");
    });
    
}
image

3個任務是并行執行,且一共花費3s執行,然后才執行任務4。如果這樣想串行執行3個任務,只需要把 全局隊列 換成 自定義隊列 即可。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容