NSOperation

轉(zhuǎn)載自:NSOperation

我們都知道,讓程序瞬間加載并且快速響應(yīng)的秘訣在于后臺異步執(zhí)行。

現(xiàn)在的OC開發(fā)者一般有兩個選擇,分別是Grand Central Dispatch或者NSOperation
。現(xiàn)在GCD已經(jīng)逐漸發(fā)展成為主流了。不過,我們今天要談的后者,一個面向?qū)ο蟮慕鉀Q辦法。

NSOperation表示了一個獨(dú)立的計(jì)算單元。作為一個抽象類,它給了它的子類一個十分有用而且線程安全的方式來建立狀態(tài)、優(yōu)先級、依賴性和取消等的模型。或者,你不是很喜歡再自己繼承NSOperation的話,框架還提供了NSBlockOperation,這是一個繼承自NSOperation且封裝了block的實(shí)體類。

很多執(zhí)行任務(wù)的案例都很好的運(yùn)用了NSOperation,包括網(wǎng)絡(luò)請求,圖像壓縮,自然語言處理或者其他很多需要返回處理后數(shù)據(jù)的、可重復(fù)的、結(jié)構(gòu)化的、相對長時間運(yùn)行的任務(wù)。

但是僅僅把計(jì)算封裝進(jìn)一個對象而不做其他處理顯然沒有多大的用處,我們還需要NSOperationQueue來大顯身手。

NSOperationQueue控制著這些并行操作的執(zhí)行,它扮演著優(yōu)先級隊(duì)列的角色,讓它管理的高優(yōu)先級操作(NSOperation -queuePriority)能優(yōu)先于低優(yōu)先級的操作運(yùn)行的情況下,使它的管理操作能基本遵循先進(jìn)先出的原則執(zhí)行。此外,在你設(shè)置了能并行運(yùn)行的操作的最大值(maxConcurrentOperationCount)之后,NSOperationQueue還能并行執(zhí)行操作。

讓一個NSOperation操作開始,你可以直接調(diào)用-start,或者將它添加到NSOperationQueue中,添加之后,它會在隊(duì)列排到它以后自動執(zhí)行。

現(xiàn)在讓我們通過怎樣使用和怎樣通過繼承實(shí)現(xiàn)功能來看看NSOperation稍微復(fù)雜的部分。

狀態(tài)

NSOperation包含了一個十分優(yōu)雅的狀態(tài)機(jī)來描述每一個操作的執(zhí)行。

isReady → isExecuting → isFinished

為了替代不那么清晰的state屬性,狀態(tài)直接由上面那些keyPath的KVO通知決定,也就是說,當(dāng)一個操作在準(zhǔn)備好被執(zhí)行的時候,它發(fā)送了一個KVO通知給isReady的keypath,讓這個keypath和對應(yīng)的屬性isReady在訪問的時候返回YES。

每一個屬性對于其他的屬性必須是互相獨(dú)立不同的,也就是同時只可能有一個屬性返回YES,從而才能維護(hù)一個連續(xù)的狀態(tài):- isReady: 返回 YES 表示操作已經(jīng)準(zhǔn)備好被執(zhí)行, 如果返回NO則說明還有其他先前的相關(guān)步驟沒有完成。 - isExecuting: 返回YES表示操作正在執(zhí)行,反之則沒在執(zhí)行。 - isFinished : 返回YES表示操作執(zhí)行成功或者被取消了,NSOperationQueue只有當(dāng)它管理的所有操作的isFinished屬性全標(biāo)為YES以后操作才停止出列,也就是隊(duì)列停止運(yùn)行,所以正確實(shí)現(xiàn)這個方法對于避免死鎖很關(guān)鍵

取消

早些取消那些沒必要的操作是十分有用的。取消的原因可能包括用戶的明確操作或者某個相關(guān)的操作失敗。

與之前的執(zhí)行狀態(tài)類似,當(dāng)NSOperation的-cancle狀態(tài)調(diào)用的時候會通過KVO通知isCancelled的keypath來修改isCancelled屬性的返回值,NSOperation需要盡快地清理一些內(nèi)部細(xì)節(jié),而后到達(dá)一個合適的最終狀態(tài)。特別的,這個時候isCancelled和isFinished的值將是YES,而isExecuting的值則為NO。

有一件肯定需要注意的事情就是關(guān)于單詞“cancel”的拼法特性,盡管各類英語的習(xí)慣不盡相同,但是對于NSOperation來說:-cancel:方法調(diào)用里只需要一個L(東西)- isCancelled:屬性里需要兩個L(形同詞)。

優(yōu)先級

不可能所有的操作都是一樣重要,通過以下的順序設(shè)置queuePriority屬性可以加快或者推遲操作的執(zhí)行:

  • NSOperationQueuePriorityVeryHigh
  • NSOperationQueuePriorityHigh
  • NSOperationQueuePriorityNormal
  • NSOperationQueuePriorityLow
  • NSOperationQueuePriorityVeryLow

此外,有些操作還可以指定threadPriority的值,它的取值返回可以從0.0到1.0,1.0代表最高的優(yōu)先級。鑒于queuePriority屬性決定了操作執(zhí)行的順序,threadPriority則指定了當(dāng)前操作開始執(zhí)行以后的CPU計(jì)算能力的分配,如果你不知道這是什么,好吧,你可能根本沒必要知道這是什么。

依賴性

根據(jù)你應(yīng)用的復(fù)雜度不同,將大任務(wù)再分成一系列子任務(wù)一般都是很有意義的,而你能通過NSOperation的依賴性實(shí)現(xiàn)。

比如說,對于服務(wù)器下載并壓縮一張圖片的整個過程 ,你可能會將這個整個過程分為兩個操作(可能你還會用到這個網(wǎng)絡(luò)子過程再去下載另一張圖片,然后用壓縮子過程去壓縮磁盤上的圖片)。顯然圖片需要等到下載完成之后才能被調(diào)整尺寸,所以我們定義網(wǎng)絡(luò)子操作的依賴,通過代碼來說就是:

[resizingOperation addDependency:networkingOperation];
[operationQueue addOperation:networkingOperation];
[operationQueue addOperation:resizingOperation];

除非一個操作的依賴的isFininished返回YES,不然這個操作不會開始。時時牢記將所有的依賴關(guān)系添加到操作隊(duì)列很重要,不然會像走路遇到一條大溝,就走不過去了幺。

此外,確保不要意外地創(chuàng)建依賴循環(huán),像A依賴B,B又依賴A,這也會導(dǎo)致悲劇的死鎖。

completionBlock

有一個在iOS 4和Snow Leopard新加入的十分有用的功能就是completionBlock屬性。

每當(dāng)一個NSOperation執(zhí)行完畢,它就會調(diào)用它的completionBlock屬性一次,這提供了一個非常好的方式讓你能在視圖控制器(ViewController)里或者模型(Model)里加入自己更多的自己的邏輯代碼。比如說,你可以在一個網(wǎng)絡(luò)請求操作的completionBlock來處理操作執(zhí)行完以后從服務(wù)器下載下來的數(shù)據(jù)。


對于現(xiàn)在OC程序員必須掌握的工具中,NSOperation依然是最基本的一個。盡管GCD對于內(nèi)嵌異步操作十分理想,NSOperation依舊提供更復(fù)雜、面向?qū)ο蟮挠?jì)算模型,它對于涉及到各種類型數(shù)據(jù)、需要重復(fù)處理任務(wù)又是更加理想的。在你的下一個項(xiàng)目里使用它吧,讓它及帶給用戶歡樂,你自己也會很開心的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 一、簡介 除了,NSThread和GCD實(shí)現(xiàn)多線程,配合使用NSOperation和NSOperationQueu...
    怎樣m閱讀 1,012評論 0 5
  • 我們在前面兩節(jié)分別講了iOS多線程的Pthrea、NSThread和GCD,那么我們關(guān)于多線程的學(xué)習(xí)就剩下最后一個...
    隨風(fēng)流逝閱讀 320評論 0 0
  • 本文翻譯matt文章NSOperation 在現(xiàn)實(shí)生活中,有很多工作要做。每一天都有源源不斷的任務(wù)填充在我們工作...
    Shawn_Wang閱讀 1,655評論 5 9
  • 轉(zhuǎn)載:http://nshipster.cn/nsoperation/ 我們都知道,讓程序瞬間加載并且快速響應(yīng)的秘...
    梅西121閱讀 238評論 0 0
  • 一、多線程簡介: 所謂多線程是指一個 進(jìn)程 -- process(可以理解為系統(tǒng)中正在運(yùn)行的一個應(yīng)用程序)中可以開...
    尋形覓影閱讀 1,092評論 0 6