珊欄函式 iOS之多執行緒GCD(三)
場景需求:需要非同步完成三個任務。任務一、任務二、任務三。要求:任務三必須在任務一、任務二完成之後觸發。這就需要使用dispatch_barrier_async。
特點:像一堵圍牆、成為任務的分割線。
程式碼如下:
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ //任務1 for (int i = 0; i < 2; i++) { NSLog(@"我是任務一、來自執行緒:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務2 for (int i = 0; i < 2 ; i++) { NSLog(@"我是任務二、來自執行緒:%@",[NSThread currentThread]); } }); dispatch_barrier_async(queue, ^{ //珊欄 for (int i = 0; i < 1 ; i++) { NSLog(@"我是分割線、來自執行緒:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務3 for (int i = 0; i < 1 ; i++) { NSLog(@"我是任務三、來自執行緒:%@",[NSThread currentThread]); } }); 複製程式碼
分析:任務一和任務二相互交錯執行、由於珊欄函式存在、任務三最後執行。這三個任務都是非同步完成、在各自的執行緒裡。
dispatch_barrier_async 、dispatch_barrier_sync區別
直接看如下程式碼:
1.dispatch_barrier_async
NSLog(@"開始啦"); dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ //任務1 for (int i = 0; i < 2; i++) { NSLog(@"我是任務一、來自執行緒:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務2 for (int i = 0; i < 2 ; i++) { NSLog(@"我是任務二、來自執行緒:%@",[NSThread currentThread]); } }); NSLog(@"動啊動啊"); dispatch_barrier_async(queue, ^{ //珊欄 for (int i = 0; i < 1 ; i++) { NSLog(@"我是分割線、來自執行緒:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務3 for (int i = 0; i < 1 ; i++) { NSLog(@"我是任務三、來自執行緒:%@",[NSThread currentThread]); } }); NSLog(@"結束啦"); 複製程式碼
列印結果:
2019-01-25 13:47:17.656139+0800 多執行緒demo[4912:51826] 開始啦 2019-01-25 13:47:17.656348+0800 多執行緒demo[4912:51826] 動啊動啊 2019-01-25 13:47:17.656463+0800 多執行緒demo[4912:51882] 我是任務一、來自執行緒:<NSThread: 0x60000047f740>{number = 3, name = (null)} 2019-01-25 13:47:17.656470+0800 多執行緒demo[4912:51884] 我是任務二、來自執行緒:<NSThread: 0x60000047ed00>{number = 4, name = (null)} 2019-01-25 13:47:17.656599+0800 多執行緒demo[4912:51826] 結束啦 2019-01-25 13:47:17.656654+0800 多執行緒demo[4912:51884] 我是任務二、來自執行緒:<NSThread: 0x60000047ed00>{number = 4, name = (null)} 2019-01-25 13:47:17.656654+0800 多執行緒demo[4912:51882] 我是任務一、來自執行緒:<NSThread: 0x60000047f740>{number = 3, name = (null)} 2019-01-25 13:47:17.657139+0800 多執行緒demo[4912:51882] 我是分割線、來自執行緒:<NSThread: 0x60000047f740>{number = 3, name = (null)} 2019-01-25 13:47:17.657313+0800 多執行緒demo[4912:51882] 我是任務三、來自執行緒:<NSThread: 0x60000047f740>{number = 3, name = (null)} 複製程式碼
分析:任務三確實在任務一、任務二之後完成。使用dispatch_barrier_async、體現了非同步的特點、不做任何等待、直接返回。所以主執行緒中的列印、不會在珊欄函式後面。
2.dispatch_barrier_sync
程式碼如下:
NSLog(@"開始啦"); dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ //任務1 for (int i = 0; i < 2; i++) { NSLog(@"我是任務一、來自執行緒:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務2 for (int i = 0; i < 2 ; i++) { NSLog(@"我是任務二、來自執行緒:%@",[NSThread currentThread]); } }); NSLog(@"動次打次:%@",[NSThread currentThread]); dispatch_barrier_sync(queue, ^{ //珊欄 for (int i = 0; i < 1 ; i++) { NSLog(@"我是分割線、來自執行緒:%@",[NSThread currentThread]); } }); dispatch_async(queue, ^{ //任務3 for (int i = 0; i < 1 ; i++) { NSLog(@"我是任務三、來自執行緒:%@",[NSThread currentThread]); } }); NSLog(@"結束啦"); 複製程式碼
列印結果:
2019-01-25 13:54:09.045223+0800 多執行緒demo[5014:57352] 開始啦 2019-01-25 13:54:09.045461+0800 多執行緒demo[5014:57352] 動次打次:<NSThread: 0x600000072f00>{number = 1, name = main} 2019-01-25 13:54:09.045486+0800 多執行緒demo[5014:57400] 我是任務二、來自執行緒:<NSThread: 0x60000026dd80>{number = 4, name = (null)} 2019-01-25 13:54:09.045496+0800 多執行緒demo[5014:57404] 我是任務一、來自執行緒:<NSThread: 0x600000260b80>{number = 3, name = (null)} 2019-01-25 13:54:09.045758+0800 多執行緒demo[5014:57400] 我是任務二、來自執行緒:<NSThread: 0x60000026dd80>{number = 4, name = (null)} 2019-01-25 13:54:09.045830+0800 多執行緒demo[5014:57404] 我是任務一、來自執行緒:<NSThread: 0x600000260b80>{number = 3, name = (null)} 2019-01-25 13:54:09.045991+0800 多執行緒demo[5014:57352] 我是分割線、來自執行緒:<NSThread: 0x600000072f00>{number = 1, name = main} 2019-01-25 13:54:09.046099+0800 多執行緒demo[5014:57352] 結束啦 2019-01-25 13:54:09.046124+0800 多執行緒demo[5014:57404] 我是任務三、來自執行緒:<NSThread: 0x600000260b80>{number = 3, name = (null)} 複製程式碼
分析:確實分割了前後執行的任務