GCD之dispatch_group詳解

dispatch_group

通常我們執(zhí)行耗時操作會放到子線程中并發(fā)執(zhí)行,這個過程中我們可能想知道各個任務(wù)全部執(zhí)行完畢的時刻,當(dāng)然我們可以通過記錄一些標(biāo)志位等手段來達到要求,但是可能步驟會比較復(fù)雜.強大的GCD中的dispatch_group_t可以輕松幫我們達到目的.

我們先來看group中的api
  • dispatch_group_async
//將block(任務(wù))提交到指定的隊列中,并且將次任務(wù)放到(關(guān)聯(lián))指定的group,block將異步執(zhí)行.
void dispatch_group_async(dispatch_group_t group,dispatch_queue_t queue,dispatch_block_t block);
//上面方法的函數(shù)版本.接受一個函數(shù)指針.
void dispatch_group_async_f(dispatch_group_t group,dispatch_queue_t queue,void *_Nullable context,dispatch_function_t work);
  • dispatch_group_wait
//這個方法會同步的等,接受一個timeout,group的任務(wù)全部完成或者超時以后會返回,返回值為0代表任務(wù)完成,非0代表超時.
long dispatch_group_wait(dispatch_group_t group,dispatch_time_t timeout);
  • dispatch_group_notify
//當(dāng)group中的任務(wù)都完成以后會執(zhí)行block.注意這句代碼要加到所有任務(wù)提交之后才管用.參數(shù)queue代表block會提交到哪個隊列中.
void dispatch_group_notify(dispatch_group_t group,dispatch_queue_t queue,dispatch_block_t block);
//上面方法的函數(shù)版本
void dispatch_group_notify_f(dispatch_group_t group,dispatch_queue_t queue,void *_Nullable context,dispatch_function_t work);
  • dispatch_group_enter
//用這個方法指定一個操作將要加到group中,用來替代`dispatch_group_async`,注意它只能和`dispatch_group_leave`配對使用.
void dispatch_group_enter(dispatch_group_t group);
  • dispatch_group_leave
//指定一個任務(wù)完成了.只能和`dispatch_group_enter`配對使用.
void dispatch_group_leave(dispatch_group_t group);
使用案例
dispatch_group_async
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.GCDDemo.queue",DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, concurrentQueue, ^{
[NSThread sleepForTimeInterval:2.0];
NSLog(@"first download task success! %@",[NSThread currentThread]);
});
dispatch_group_async(group, concurrentQueue, ^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"second download task success! %@",[NSThread currentThread]);
});
dispatch_group_notify(group, concurrentQueue, ^{
NSLog(@"begin task three! %@",[NSThread currentThread]);
});
輸出臺:
second download task success! <NSThread: 0x600000279c80>{number = 4, name = (null)}
first download task success! <NSThread: 0x6080002674c0>{number = 3, name = (null)}
begin task three! <NSThread: 0x6080002674c0>{number = 3, name = (null)}
dispatch_group_enter & dispatch_group_leave
  • 個人感覺這種方式比dispatch_group_async更加靈活.比如我們可以在任務(wù)的完成回調(diào)里面寫dispatch_group_leave().
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.GCDDemo.concurrentQueue",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t serialQueue = dispatch_queue_create("com.GCDDemo.serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_async(concurrentQueue, ^{
[NSThread sleepForTimeInterval:2.0];
NSLog(@"first download task success! %@",[NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(serialQueue, ^{
[NSThread sleepForTimeInterval:2.0];
NSLog(@"second download task success! %@",[NSThread currentThread]);
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_async(serialQueue, ^{
[NSThread sleepForTimeInterval:2.0];
NSLog(@"three download task success! %@",[NSThread currentThread]);
dispatch_group_leave(group);
});
//超時處理.
long result = dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC));
if (result == 0) {
NSLog(@"success");
}else {
NSLog(@"time out!");
}
dispatch_group_notify(group, concurrentQueue, ^{
NSLog(@"begin task three! %@",[NSThread currentThread]);
});
//輸出臺:
time out!
first download task success! <NSThread: 0x608000277200>{number = 4, name = (null)}
second download task success! <NSThread: 0x608000270c40>{number = 3, name = (null)}
three download task success! <NSThread: 0x608000270c40>{number = 3, name = (null)}
begin task three! <NSThread: 0x608000277200>{number = 4, name = (null)}
注意我的任務(wù)1放在了并發(fā)隊列中,任務(wù)2,和任務(wù)3放在了串行隊列中,所以你看到的打印順序是任務(wù)1和任務(wù)2幾乎同時打印,任務(wù)3等2秒后打印,(在任務(wù)2之后).
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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