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