NSOperation原理

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

現(xiàn)在的Objective-C開發(fā)者一般有兩個選擇他匪,分別是Grand Central Dispatch或者NSOperation。現(xiàn)在GCD已經(jīng)逐漸發(fā)展成主流了夸研,所以我們來談?wù)労笳甙蠲郏粋€面向?qū)ο蟮慕鉀Q辦法。

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

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

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

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

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

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

狀態(tài)

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

isReady → isExecuting → isFinished

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

每一個屬性對于其他的屬性必須是互相獨立不同的统捶,也就是同時只可能有一個屬性返回YES榆芦,從而才能維護一個連續(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以后操作才停止出列迷守,也就是隊列停止運行犬绒,所以正確實現(xiàn)這個方法對于避免死鎖很關(guān)鍵。

取消

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

與之前的執(zhí)行狀態(tài)類似茵瘾,當(dāng)NSOperation的-cancel狀態(tài)調(diào)用的時候會通過KVO通知isCancelled的keypath來修改isCancelled屬性的返回值,NSOperation需要盡快地清理一些內(nèi)部細(xì)節(jié)咐鹤,而后到達一個合適的最終狀態(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ù)你應(yīng)用的復(fù)雜度不同,將大任務(wù)再分成一系列子任務(wù)一般都是很有意義的翠拣,而你能通過NSOperation的依賴性實現(xiàn)版仔。

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

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

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

此外妨蛹,確保不要意外地創(chuàng)建依賴循環(huán),像A依賴B晴竞,B又依賴A蛙卤,這也會導(dǎo)致杯具的死鎖。

completionBlock

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

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

對于現(xiàn)在Objective-C程序員必須掌握的工具中,NSOperation依然是最基本的一個栅屏。盡管GCD對于內(nèi)嵌異步操作十分理想飘千,NSOperation依舊提供更復(fù)雜、面向?qū)ο蟮挠嬎隳P图惹伲鼘τ谏婕暗礁鞣N類型數(shù)據(jù)占婉、需要重復(fù)處理的任務(wù)又是更加理想的泡嘴。在你的下一個項目里使用它吧甫恩,讓它及帶給用戶歡樂,你自己也會很開心的酌予。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末磺箕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子抛虫,更是在濱河造成了極大的恐慌松靡,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件建椰,死亡現(xiàn)場離奇詭異雕欺,居然都是意外死亡,警方通過查閱死者的電腦和手機棉姐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門屠列,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伞矩,你說我怎么就攤上這事笛洛。” “怎么了乃坤?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵苛让,是天一觀的道長。 經(jīng)常有香客問我湿诊,道長狱杰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任厅须,我火速辦了婚禮仿畸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘九杂。我一直安慰自己颁湖,他們只是感情好宣蠕,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甥捺,像睡著了一般抢蚀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上镰禾,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天皿曲,我揣著相機與錄音,去河邊找鬼吴侦。 笑死屋休,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的备韧。 我是一名探鬼主播劫樟,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼织堂!你這毒婦竟也來了叠艳?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤易阳,失蹤者是張志新(化名)和其女友劉穎附较,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體潦俺,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡拒课,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了事示。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片早像。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖很魂,靈堂內(nèi)的尸體忽然破棺而出扎酷,到底是詐尸還是另有隱情,我是刑警寧澤遏匆,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布法挨,位于F島的核電站,受9級特大地震影響幅聘,放射性物質(zhì)發(fā)生泄漏凡纳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一帝蒿、第九天 我趴在偏房一處隱蔽的房頂上張望荐糜。 院中可真熱鬧,春花似錦、人聲如沸暴氏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽答渔。三九已至关带,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沼撕,已是汗流浹背宋雏。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留务豺,地道東北人磨总。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像笼沥,于是被迫代替她去往敵國和親蚪燕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

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