概念了解一下
在組合中昼接,左邊四個(gè)容易理解(一般是獲取系統(tǒng)提供的全局隊(duì)列 dispatch_get_global_queue())虫啥,不再贅述掺逼。
要敘述的是在主隊(duì)列中執(zhí)行同步異步任務(wù)的情況。
主隊(duì)列異步:主隊(duì)列是串行隊(duì)列宋税,只有一個(gè)線程(主線程)摊崭,任務(wù)要順序執(zhí)行,但因?yàn)楫惒降脑蚪苋蝿?wù)創(chuàng)建完畢放在隊(duì)列尾部(FIFO)。代碼可以正常執(zhí)行矮台。
主隊(duì)列同步:死鎖乏屯。
dispatch_sync(dispatch_get_main_queue, ^(){
NSLog(@"死鎖");
);
關(guān)于這個(gè)問(wèn)題,網(wǎng)上太多解答了瘦赫。有個(gè)大神用源碼解讀死鎖的問(wèn)題感興趣再點(diǎn)辰晕。
大神的解答太深?yuàn)W,我只記錄一個(gè)能說(shuō)服我的理論就可以了确虱。
主隊(duì)列是串行隊(duì)列含友,只有一個(gè)線程(主線程),任務(wù)要順序執(zhí)行校辩,組合同步任務(wù)的時(shí)候窘问,任務(wù)創(chuàng)建完畢放在隊(duì)列尾部(FIFO)。但是因?yàn)橥饺蝿?wù)的關(guān)系宜咒,任務(wù)創(chuàng)建完就要執(zhí)行惠赫,此刻它會(huì)與主線程搶占資源 -> 主線程要執(zhí)行完它之前的任務(wù)(拿到sync函數(shù)的返回值)再執(zhí)行這個(gè)同步任務(wù)(打印)故黑,而同步任務(wù)要求主線程馬上執(zhí)行(打佣邸)。造成了死鎖场晶。
還有一些小皮們混埠,非要在主線程執(zhí)行同步任務(wù),也不是沒(méi)辦法
“1”
dispatch_async(dispatch_get_global_queue, ^(){
NSLog(@"2");
dispatch_sync(dispatch_get_main_queue, ^(){
NSLog(@"3");
);
“4”
);
“5”
哇塞 看了諸多解釋后才感覺(jué)有點(diǎn)眉目了诗轻。很多帖子看完了钳宪,有人評(píng)論說(shuō)是觀點(diǎn)是錯(cuò)的。我的媽呀。直到看到這句話
對(duì)于在主線程使套,你可以認(rèn)為每一語(yǔ)句都是將任務(wù)插入主隊(duì)列罐呼。調(diào)用dispatch_sync這個(gè)函數(shù)相當(dāng)于將一個(gè)任務(wù)插入主隊(duì)列,這個(gè)函數(shù)的作用是將一個(gè)任務(wù)插入指定隊(duì)列侦高,當(dāng)這個(gè)函數(shù)里的Block執(zhí)行完畢以后嫉柴,這個(gè)函數(shù)才會(huì)返回,即這個(gè)調(diào)用這個(gè)dispatch_sync的任務(wù)結(jié)束奉呛,主隊(duì)列繼續(xù)往下添加任務(wù)计螺。我上面說(shuō)了,串行的任務(wù)添加后需要等前面的任務(wù)都執(zhí)行完才會(huì)執(zhí)行的瞧壮。所以Block里的任務(wù)需要等dispatch_sync這個(gè)調(diào)用執(zhí)行完才會(huì)執(zhí)行登馒,然而dispatch_sync并不會(huì)返回。
第二個(gè)是創(chuàng)建了一個(gè)空的串行隊(duì)列咆槽,dispatch_sync這個(gè)是主隊(duì)列添加的任務(wù)陈轿,工作是將一個(gè)任務(wù)添加到這個(gè)新創(chuàng)建的隊(duì)列上,由于指定的隊(duì)列前面沒(méi)有其他任務(wù)秦忿,所以這個(gè)任務(wù)先執(zhí)行麦射,然后返回,dispatch_sync返回灯谣,主隊(duì)列繼續(xù)往下添加任務(wù)潜秋。
對(duì)于在全局并行隊(duì)列里面執(zhí)行 主隊(duì)列同步任務(wù) 不會(huì)死鎖的情況。核心的就是sync這個(gè)函數(shù)的代碼寫(xiě)在了全局隊(duì)列里胎许。這個(gè)sync任務(wù)的派發(fā)是在全局隊(duì)列中峻呛,等待這個(gè)函數(shù)返回的是全局隊(duì)列。主隊(duì)列只要負(fù)責(zé)打印即可辜窑。不存在搶占資源的情況钩述。
任務(wù)執(zhí)行順序如下圖(盜的圖)
還有特殊的 GCD組
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
NSLog(@"1");
dispatch_group_leave(group);
});
dispatch_group_enter(group);
dispatch_group_async(group, queue, ^{
NSLog(@"2");
dispatch_group_leave(group);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
});