GCD中提供了兩個函數(shù)被饿,可以實現(xiàn)此功能,分別是dispatch_barrier_(a)sync和dispatch_group_(a)sync搪搏。
簡單寫一下兩種函數(shù)的使用方式狭握。
1.dispatch_barrier_(a)sync
dispatch_queue_t queue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"111");
});
dispatch_sync(queue, ^{
NSLog(@“222”);
});
dispatch_barrier_async(queue, ^{
NSLog(@"barrier finished");
});
NSLog(@"main tread");
dispatch_async(queue, ^{
NSLog(@“333”);
});
dispatch_async(queue, ^{
NSLog(@“444”);
});
2017-12-20 14:07:11.774484+0800 GCD[33826:2126185] 111
2017-12-20 14:07:11.774517+0800 GCD[33826:2126192] 222
2017-12-20 14:07:11.774540+0800 GCD[33826:2126069] main thread
2017-12-20 14:07:11.774715+0800 GCD[33826:2126192] barrier finished
2017-12-20 14:07:11.774836+0800 GCD[33826:2126185] 333
2017-12-20 14:07:11.774837+0800 GCD[33826:2126192] 444
dispatch_barrier_async換成dispatch_barrier_sync之后log如下
2017-12-20 14:07:51.093250+0800 GCD[33878:2127341] 222
2017-12-20 14:07:51.093250+0800 GCD[33878:2127340] 111
2017-12-20 14:07:51.093466+0800 GCD[33878:2127248] barrier finished
2017-12-20 14:07:51.093604+0800 GCD[33878:2127248] main thread
2017-12-20 14:07:51.093742+0800 GCD[33878:2127341] 333
2017-12-20 14:07:51.093786+0800 GCD[33878:2127338] 444
dispatch_barrier_sync的作用是阻塞當(dāng)前線程疯溺,把queue中的所有任務(wù)執(zhí)行完畢之后论颅,再去執(zhí)行barrier的block
dispatch_barrier_async不阻塞當(dāng)前線程,調(diào)用之后囱嫩,立即返回當(dāng)前線程恃疯,繼續(xù)執(zhí)行后面的代碼。
總之挠说,dispatch_barrier_(a)sync的執(zhí)行順序就是先執(zhí)行barrier block之前的所有任務(wù)澡谭,然后執(zhí)行barrier block中的任務(wù),最后執(zhí)行barrier block之后提交的任務(wù)损俭。
2.dispatch_group
dispatch_queue_t queue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"group 1");
});
dispatch_group_async(group, queue, ^{
NSLog(@"group 2");
});
dispatch_group_async(group, queue, ^{
NSLog(@"group 3");
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"group finished");
});
NSLog(@"666");
2017-12-20 14:18:53.984247+0800 GCD[34045:2139050] group 2
2017-12-20 14:18:53.984247+0800 GCD[34045:2139052] group 1
2017-12-20 14:18:53.984247+0800 GCD[34045:2139051] group 3
2017-12-20 14:18:53.984775+0800 GCD[34045:2138995] 666
2017-12-20 14:18:53.990947+0800 GCD[34045:2138995] group finished
與dispatch_barrier_(a)sync不同的是加入到group中的queue可以是不同的queue。
如果我們執(zhí)行異步請求的時候如何保證在異步任務(wù)完成后潘酗,再去執(zhí)行某段代碼呢杆兵?這時候就要用到dispatch_group_enter和dispatch_group_leave了
dispatch_group_enter和dispatch_group_leave是成對出現(xiàn)的,出現(xiàn)數(shù)量必須保持一致仔夺。
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:2];//發(fā)送一個網(wǎng)絡(luò)請求
NSLog(@"1111");
dispatch_group_leave(group);
});
});
dispatch_group_async(group, queue, ^{
NSLog(@"group 2");
});
dispatch_group_async(group, queue, ^{
NSLog(@"group 3");
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"group finished");
});
NSLog(@"666");
2017-12-20 14:24:17.069952+0800 GCD[34215:2145287] group 2
2017-12-20 14:24:17.069952+0800 GCD[34215:2145285] group 3
2017-12-20 14:24:19.070292+0800 GCD[34215:2145288] 1111
2017-12-20 14:24:19.070640+0800 GCD[34215:2145119] 666
2017-12-20 14:24:19.076618+0800 GCD[34215:2145119] group finished
這樣就可以用來處理多個異步任務(wù)琐脏,任務(wù)完成后統(tǒng)一處理任務(wù)邏輯了。