NSOperation

轉(zhuǎn)載:http://nshipster.cn/nsoperation/


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

現(xiàn)在的Objective-C開發(fā)者一般有兩個(gè)選擇迁沫,分別是Grand Central Dispatch或者NSOperation△⒃郏現(xiàn)在GCD已經(jīng)逐漸發(fā)展成主流了嘴秸,所以我們來談?wù)労笳咚帕保粋€(gè)面向?qū)ο蟮慕鉀Q辦法凑队。

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

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

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

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

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

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

狀態(tài)

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

isReady→isExecuting→isFinished

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

每一個(gè)屬性對(duì)于其他的屬性必須是互相獨(dú)立不同的决左,也就是同時(shí)只可能有一個(gè)屬性返回YES,從而才能維護(hù)一個(gè)連續(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)這個(gè)方法對(duì)于避免死鎖很關(guān)鍵。

取消

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

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

有一件肯定需要注意的事情就是關(guān)于單詞"cancel"的拼法特性,盡管各類英語(yǔ)的習(xí)慣不盡相同半哟,但是對(duì)于NSOperation來說:-cancel: 方法調(diào)用里只需要一個(gè)L(動(dòng)詞)-isCancelled: 屬性里需要兩個(gè)L(形容詞)

優(yōu)先級(jí)

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

NSOperationQueuePriorityVeryHigh

NSOperationQueuePriorityHigh

NSOperationQueuePriorityNormal

NSOperationQueuePriorityLow

NSOperationQueuePriorityVeryLow

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

依賴性

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

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

Objective-C

[resizingOperationaddDependency:networkingOperation];[operationQueueaddOperation:networkingOperation];[operationQueueaddOperation:resizingOperation];

除非一個(gè)操作的依賴的isFinished返回YES,不然這個(gè)操作不會(huì)開始第股。時(shí)時(shí)牢記將所有的依賴關(guān)系添加到操作隊(duì)列很重要,不然會(huì)像走路遇到一條大溝诲锹,就走不過去了喲涉馅。

此外,確保不要意外地創(chuàng)建依賴循環(huán)控漠,像A依賴B悬钳,B又依賴A,這也會(huì)導(dǎo)致杯具的死鎖碉渡。

completionBlock

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末焚刺,一起剝皮案震驚了整個(gè)濱河市门烂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蔓姚,老刑警劉巖慨丐,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異房揭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)恬砂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門蓬痒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瞪讼,你說我怎么就攤上這事》罚” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵诊沪,是天一觀的道長(zhǎng)曾撤。 經(jīng)常有香客問我,道長(zhǎng)渐裸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任昏鹃,我火速辦了婚禮诀诊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘载迄。我一直安慰自己抡蛙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著极祸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浴捆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天选泻,我揣著相機(jī)與錄音,去河邊找鬼梯捕。 笑死窝撵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碌奉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嫉拐,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼魁兼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起璃赡,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤碉考,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后侯谁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡热芹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年惨撇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片报腔。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剖淀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出纵隔,到底是詐尸還是另有隱情炮姨,我是刑警寧澤碰煌,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布拄查,位于F島的核電站吁津,受9級(jí)特大地震影響堕扶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜典尾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一糊探、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧科平,春花似錦、人聲如沸髓考。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)妓湘。三九已至,卻和暖如春榜贴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鹃共。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工初嘹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沮趣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓驻龟,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親翁狐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • 一闯冷、簡(jiǎn)介 除了懈词,NSThread和GCD實(shí)現(xiàn)多線程,配合使用NSOperation和NSOperationQueu...
    怎樣m閱讀 980評(píng)論 0 5
  • 我們?cè)谇懊鎯晒?jié)分別講了iOS多線程的Pthrea纺涤、NSThread和GCD抠忘,那么我們關(guān)于多線程的學(xué)習(xí)就剩下最后一個(gè)...
    隨風(fēng)流逝閱讀 303評(píng)論 0 0
  • 本文翻譯matt文章NSOperation 在現(xiàn)實(shí)生活中,有很多工作要做崎脉。每一天都有源源不斷的任務(wù)填充在我們工作...
    Shawn_Wang閱讀 1,624評(píng)論 5 9
  • 轉(zhuǎn)載自:NSOperation 我們都知道荧嵌,讓程序瞬間加載并且快速響應(yīng)的秘訣在于后臺(tái)異步執(zhí)行。 現(xiàn)在的OC開發(fā)者一...
    夏天的風(fēng)_song閱讀 152評(píng)論 0 0
  • 對(duì)于iOS的并發(fā)編程, 用的最普遍的就是GCD了, GCD結(jié)合Block可以so easy的實(shí)現(xiàn)多線程并發(fā)編程. ...
    金小俊閱讀 7,964評(píng)論 32 136