GCD 掃盲篇
轉(zhuǎn)載地址
GCD有四個概念:串行隊列、并行隊列雳攘、同步、異步四者枫笛。
如下簡介:
這里不僅給出了不確定性吨灭,而且也給出了確定性。對于初學(xué)者而言刑巧,有時候因為那些不確定的東西所造成的疑問會像沒有閘卻在疾馳的汽車一樣讓人驚慌失措喧兄,而“確定性”就如同這救命的車閘一樣无畔,它能讓你豁然開朗。
名稱 | 功能特點 | 確定性解釋 | 不確定性解釋 |
---|---|---|---|
同步 | 完成需要做的任務(wù)后才會返回吠冤,進行下一任務(wù) | “任務(wù)”浑彰,在 GCD 里指的是 Block;在 performSelector 方法中拯辙,對應(yīng) selector 方法郭变。</p>同步方法,功能類似 dispatch_group_wait 涯保,而 group 指的是所有線程诉濒,包括主線程。 |
</p> 不一定是多線程 |
異步 | 不會等待任務(wù)完成才返回遭赂,會立即返回循诉。 | 異步是多線程的代名詞,因為必定會開啟新的線程撇他,線程的申請是由異步負責(zé)茄猫,起到開分支的作用。 | -- |
串行隊列 | 任務(wù)依次執(zhí)行 | 同一時間隊列中只有一個任務(wù)在執(zhí)行困肩,每個任務(wù)只有在前一個任務(wù)執(zhí)行完成后才能開始執(zhí)行划纽。 | 你不知道在一個Block(任務(wù))執(zhí)行結(jié)束到下一個Block(任務(wù))開始執(zhí)行之間的這段時間時間是多長, |
并行隊列 | 任務(wù)并發(fā)執(zhí)行 | 你唯一能保證的是锌畸,這些任務(wù)會按照被添加的順序開始執(zhí)行勇劣。但是任務(wù)可以以任何順序完成 | 你不知道在執(zhí)行下一個任務(wù)是從什么時候開始,或者說任意時刻有多個Block(任務(wù))運行潭枣,這個完全是取決于GCD比默。 |
全局隊列 | 隸屬于并行隊列 | 不要與 barrier 柵欄方法搭配使用, barrier 只有與自定義的并行隊列一起使用盆犁,才能讓 barrier 達到我們所期望的柵欄功能命咐。與 串行隊列或者 global 隊列 一起使用,barrier 的表現(xiàn)會和 dispatch_sync 方法一樣谐岁。 | |
主隊列 | 隸屬于串行隊列 | 不能與 sync 同步方法搭配使用醋奠,會造成死循環(huán) |
串行隊列、并行隊列伊佃、同步窜司、異步四者的組合:
GCD提供了dispatch queues(調(diào)度隊列)來執(zhí)行代碼段,這些隊列以FIFO(先進先出)的方式來管理你用GCD提交的任務(wù)航揉。這保證了你先提交的任務(wù)現(xiàn)執(zhí)行塞祈,即第一個任務(wù)添加到隊列中就第一個開始執(zhí)行,第二個添加的任務(wù)將第二個執(zhí)行帅涂,知道隊列的最后一個任務(wù)织咧。
--- | 同步 | 異步 |
---|---|---|
串行隊列 | 不會新建線程胀葱,依然在當(dāng)前線程上</p>類似同步鎖,是同步鎖的替代方案</p>? 常用 | 會新建線程笙蒙,只開一條線程</p>一條線程就夠了</p> 每次使用 createDispatch 方法就會新建一條線程,多次調(diào)用該方法庆锦,會創(chuàng)建多條線程捅位,多條線程間會并行執(zhí)行 |
并行隊列 | 不會新建線程,依然在當(dāng)前線程上</p> | 會新建線程搂抒,可以開多條線程</p> iOS7-SDK 時代一般是5艇搀、6條, iOS8-SDK 以后可以50求晶、60條 </p> ? 常用 |
參考鏈接: Why can't we use a dispatch_sync on the current queue?
串行隊列中的同步與異步的區(qū)別
串行隊列能確保順序執(zhí)行任務(wù)焰雕,他們兩個的唯一區(qū)別在于dispatch_sync
只會在 block 完全執(zhí)行完之后返回,dispatch_async
不能確保會在 block 完全執(zhí)行完之后返回芳杏,唯一能確定的是會在被添加到queue 隊列后返回矩屁。
下面的代碼:
dispatch_async(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_async(_serialQueue, ^{ printf("3"); });
printf("4");
可能會打印 2413
、 2143
爵赵、 1234
吝秕,但有一點是可以確認的: 1
總是在 3
之前。
可能的打涌栈谩:
1
2
3
4
----------
2
4
1
3
1
2
3
4
----------
2
4
1
3
然而下面的代碼:
dispatch_sync(_serialQueue, ^{ printf("1"); });
printf("2");
dispatch_sync(_serialQueue, ^{ printf("3"); });
printf("4");
總會打铀盖汀:1234
參考鏈接: Difference between dispatch_async and dispatch_sync on serial queue?