NSOperation是一個(gè)抽象類,用來封裝任務(wù)的代碼和數(shù)據(jù),不能直接使用該類而是使用系統(tǒng)定義的子類來完成實(shí)際的任務(wù)。
兩種默認(rèn)實(shí)現(xiàn):NSInvocationOperation/NSBlockOperation
需調(diào)用start方法執(zhí)行其任務(wù),執(zhí)行時(shí)默認(rèn)在當(dāng)前線程中執(zhí)行,即默認(rèn)同步執(zhí)行,注意:一個(gè)operation對(duì)象只能執(zhí)行一次,再次start不會(huì)執(zhí)行block中的內(nèi)容。
子類化NSOperation 并在main函數(shù)中添加需要執(zhí)行的任務(wù),這里的main方法會(huì)在主線程中執(zhí)行。
NSBlockOperation 還有一個(gè)方法:addExecutionBlock: ,通過這個(gè)方法可以給 Operation 添加多個(gè)執(zhí)行 Block。這樣 Operation 中的任務(wù)會(huì)并發(fā)執(zhí)行,它會(huì)在主線程和其它的多個(gè)線程執(zhí)行這些任務(wù)。
將NSOperation添加到一個(gè)操作隊(duì)列中執(zhí)行操作,來實(shí)現(xiàn)在子線程完成任務(wù),這個(gè)操作隊(duì)列可以使用NSOperationQueue來創(chuàng)建。
配合使用NSOperationQueue和NSOperation也可以實(shí)現(xiàn)多線程編程,一個(gè)NSOperationQueue對(duì)象并非一個(gè)線程,而是線程管理器,可以幫我們自動(dòng)創(chuàng)建新的線程。
創(chuàng)建隊(duì)列NSOperationQueue并添加任務(wù) 即NSOperation 任務(wù)的具體操作封裝在NSOperation中,將任務(wù)添加到隊(duì)列中時(shí)就不需要執(zhí)行start方法,系統(tǒng)會(huì)默認(rèn)將取出的NSOperation封裝的操作放到一條新線程中執(zhí)行,所有方法是獨(dú)立異步執(zhí)行的。
NSOperationQueue創(chuàng)建的線程的多少取決于隊(duì)列的最大并行數(shù)queue.maxConcurrentOperationCount
注意:最大并行數(shù)設(shè)置為一時(shí),所有任務(wù)都會(huì)串行,但并不代表所有的任務(wù)都在同一個(gè)線程中執(zhí)行。
NSOperation添加到隊(duì)列中后不要再修改NSOperation對(duì)象的狀態(tài),因?yàn)镹SOperation對(duì)象可能在任何時(shí)候運(yùn)行,此時(shí)改變其對(duì)象數(shù)據(jù)會(huì)導(dǎo)致不可預(yù)測的錯(cuò)誤。
可以通過添加任務(wù)的依賴設(shè)置任務(wù)的執(zhí)行順序:[block1 addDependency:block2];
注意:添加依賴關(guān)系后,相互依賴的任務(wù)不一定在同一條線程中執(zhí)行,不要循環(huán)的添加依賴;可以使用 removeDependency 來解除依賴關(guān)系。
優(yōu)先級(jí):優(yōu)先級(jí)高的任務(wù)調(diào)用的幾率更大 但并不一定最先執(zhí)行,優(yōu)先級(jí)不能替代依賴關(guān)系,只是對(duì)已經(jīng)準(zhǔn)備好的operations確定執(zhí)行順序,所以執(zhí)行順序是:先滿足依賴關(guān)系,再從所有準(zhǔn)備好的操作中選擇優(yōu)先級(jí)最高的先執(zhí)行。
[block1 cancel]; //取消任務(wù)
[queue cancelAllOperations]; //取消所有的任務(wù)
[queue setSuspended:YES]; //暫停隊(duì)列
暫停一個(gè)queue不會(huì)導(dǎo)致正在執(zhí)行的operation在任務(wù)中途暫停 只是阻止新operation的執(zhí)行.
何時(shí)使用:
大部分情況下使用GCD就能解決問題,但有時(shí)候(執(zhí)行后臺(tái)任務(wù)時(shí))選擇使用NSOperationQueue效果更好,需要注意使用時(shí)機(jī)。