GCD - dispatch_group 的理解及使用

介紹一下主要的函數

1、dispatch_group_async

//將block加入到queue中,并和group相關聯
void dispatch_group_async(dispatch_group_t group,
                          dispatch_queue_t queue,
                          dispatch_block_t block); 

如果提交到dispatch_queue_t queue中與group關聯的任務全都執行完畢會調用dispatch_group_notify并且dispatch_group_wait會停止等待;

2、dispatch_group_enter & dispatch_group_leave

//將代碼塊加入到group中,與dispatch_group_async功能類似
//開始一個任務
void dispatch_group_enter(dispatch_group_t group);

//結束的任務
void dispatch_group_leave(dispatch_group_t group);

當調用enter時計數加1,調用leave時計數減1,當計數為0時會調用dispatch_group_notify并且dispatch_group_wait會停止等待;

注意點: dispatch_group_enter 和 dispatch_group_leave 必須成對出現

3、dispatch_group_wait

//阻塞當前線程(不能放在主線程)等待group任務的完成,可以設置超時時間
long dispatch_group_wait(dispatch_group_t group, 
                          dispatch_time_t timeout);

4 、dispatch_group_notify

/*   dispatch_group_notify會把block加入到queue中, 
  *  當dispatch_group_t中的任務執行完成時執行
  *  或者在dispatch_group_enter和dispatch_group_leave存在的情況下,計數為0的時候執行
*/
void dispatch_group_notify(dispatch_group_t group,
                            dispatch_queue_t queue,
                            dispatch_block_t block);

示例1 dispatch_group的簡單使用:

    dispatch_queue_t queue_t = dispatch_queue_create("gcd_demo_queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group_t = dispatch_group_create();
    
    dispatch_group_async(group_t, queue_t, ^{
        sleep(2);
        NSLog(@"任務1完成");
    });
    
    dispatch_group_async(group_t, queue_t, ^{
        sleep(3);
        NSLog(@"任務2完成");
        
    });
    
    dispatch_group_async(group_t, queue_t, ^{
        NSLog(@"任務3完成");
    });
    
    //任務完成方式一
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_group_wait(group_t, DISPATCH_TIME_FOREVER);
        NSLog(@"任務完成通知 Wait");
    });
    
    //任務完成方式二
    dispatch_group_notify(group_t, dispatch_get_main_queue(), ^{
        NSLog(@"任務完成通知 Notify");
    });

輸出結果

2018-01-04 14:10:15.884470+0800 GCD_Demo[2869:439062] 任務3完成
2018-01-04 14:10:17.886704+0800 GCD_Demo[2869:439063] 任務1完成
2018-01-04 14:10:18.887726+0800 GCD_Demo[2869:439061] 任務2完成
2018-01-04 14:10:18.887978+0800 GCD_Demo[2869:439060] 任務完成通知 Wait
2018-01-04 14:10:18.887988+0800 GCD_Demo[2869:439018] 任務完成通知 Notify

需要注意的是dispatch_group_wait會阻塞當前線程,所以不能放到主線程

示例2 dispatch_group 多個queue的使用:

        dispatch_queue_t queue_t = dispatch_queue_create("gcd_demo_queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t queue_global_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group_t = dispatch_group_create();
    
    dispatch_group_async(group_t, queue_t, ^{
        sleep(2);
        NSLog(@"任務1完成");
    });
    
    dispatch_group_async(group_t, queue_t, ^{
        sleep(3);
        NSLog(@"任務2完成");
    });

    //任務3 在系統的線程中執行
    dispatch_group_async(group_t, queue_global_t, ^{
        sleep(5);
        NSLog(@"任務3完成");
    });
    
    dispatch_group_notify(group_t, dispatch_get_main_queue(), ^(){
        NSLog(@"notify:任務都完成了");
    });

輸出結果

2018-01-04 14:24:47.559384+0800 GCD_Demo[2998:488861] 任務1完成
2018-01-04 14:24:48.557911+0800 GCD_Demo[2998:488863] 任務2完成
2018-01-04 14:24:50.556268+0800 GCD_Demo[2998:488864] 任務3完成
2018-01-04 14:24:50.556476+0800 GCD_Demo[2998:488756] 任務完成通知

示例3 dispatch_group - dispatch_group_enter & dispatch_group_leave的使用:

dispatch_queue_t queue_t = dispatch_queue_create("gcd_demo_queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group_t = dispatch_group_create();
    
    dispatch_group_enter(group_t);
    dispatch_async(queue_t, ^{
        sleep(5);
        NSLog(@"網絡任務1完成");
        dispatch_group_leave(group_t);
    });
    
    dispatch_group_enter(group_t);
    dispatch_async(queue_t, ^{
        sleep(3);
        NSLog(@"網絡任務2完成");
        dispatch_group_leave(group_t);
    });
    
    dispatch_group_enter(group_t);
    dispatch_async(queue_t, ^{
        sleep(4);
        NSLog(@"網絡任務3完成");
        dispatch_group_leave(group_t);
    });
    
    dispatch_group_notify(group_t, dispatch_get_main_queue(), ^{
        NSLog(@"任務完成通知");
    });

輸出結果

2018-01-04 14:33:10.374991+0800 GCD_Demo[3110:527082] 網絡任務2完成
2018-01-04 14:33:11.374908+0800 GCD_Demo[3110:527095] 網絡任務3完成
2018-01-04 14:33:12.375411+0800 GCD_Demo[3110:526266] 網絡任務1完成
2018-01-04 14:33:12.375620+0800 GCD_Demo[3110:526111] 任務完成通知

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

推薦閱讀更多精彩內容