使用NSOperation以及NSOperationQueue

使用NSOperation以及NSOperationQueuehtml

 

NSOperation vs. Grand Central Dispatch (GCD)併發

在Mac OS X v10.6和iOS4以前,NSOperation 與 NSOperationQueue 不一樣於GCD,他們使用了徹底不一樣的機制。app

從Mac OS X v10.6和iOS4開始,NSOperation 和 NSOperationQueue是創建在GCD上的。做爲一種通例,蘋果推薦使用最高級別的抽象,然而當評估顯示有須要時,會忽然降到更低級別。ide

如下是對二者的快速比較,它會幫助你決定什麼時候何地去使用GCD或者NSOperation和NSOperationQueue;函數

  • GCD是一種輕量級的方法來表明將要被併發執行的任務單位。你並不須要去計劃這些任務單位;系統會爲你作計劃。在塊(block)中添加依賴會是一件使人頭疼的事情。取消或者暫停一個塊會給一個開發者產生額外的工做!:]
  • NSOperation和NSOperationQueue 對比GCD會帶來一點額外的系統開銷,可是你能夠在多個操做(operation)中添加附屬。你能夠重用操做,取消或者暫停他們。NSOperation和 Key-Value Observation (KVO)是兼容的;例如,你能夠經過監聽NSNotificationCenter去讓一個操做開始執行。

 

NSOperation API測試

NSOperation 類有一個至關簡短的聲明。要定製一個操做,能夠遵循如下步驟:spa

  1. 繼承NSOperation類
  2. 重寫「main」方法
  3. 在「main」方法中建立一個「autoreleasepool」
  4. 將你的代碼放在「autoreleasepool」中(ARC中也須要放在autoreleasepool中,這是爲了兼容MRC代碼)

 

爲了你可以測試代碼,請新建一個類,繼承自NSOperation,寫成以下的形式:3d

 

以後再進行操做:htm

注意,只有將一個任務添加進了隊列當中,這個任務纔會被執行.對象

如下代碼是併發執行2個任務,隊列的最大併發數是4:

 

任務具備的優先級:

當你添加了操做到一個隊列時,在對操做調用「start」方法以前,NSOperationQueue會瀏覽全部的操做。那些有較高優先級的操做會被先執行。有同等優先級的操做會按照添加到隊列中的順序去執行(先進先出)。
(歷史註釋:在1997年,火星車中的嵌入式系統遭遇過優先級反轉問題,也許這是說明正確處理優先級和互斥鎖的最昂貴示例了。想對這一事件的背景知識有更多的瞭解,能夠看這個網址: http://research.microsoft.com/en-us/um/people/mbj/Mars_Pathfinder/Mars_Pathfinder.html 

 

請添加以下的延遲方法:

 

先開始任務,1s鍾以後cancel掉一個任務:

 

每一個任務結束後都會有一個回調能夠表示任務結束:

 

任務之間的從屬關係:

 

如下來點總結:

  • 要常常檢查isCancelled屬性。若是操做不須要被執行了,你就不想在後臺去運行它了!(你從外面設置了cancell後,你是須要在方法裏面來實現cancell的哦,注意,親)
  • 你並不須要重寫「start」方法。然而,若是你決定去重寫「start」方法,就必須處理好像isExecuting, isFinished, isConcurrent 和 isReady這些屬性。不然你的操做類不會正確的運做。
  • 你一旦添加了一個操做到一個隊列(NSOperationQueue的一個實例)中,就要負責釋放它(若是你不使用ARC的話)。NSOperationQueue 得到操做對象的全部權,調用「start」方法,而後結束時負責釋放它。
  • 你不能重用一個操做對象。一旦它被添加到一個隊列中,你就喪失了對它的全部權。若是你想再使用同一個操做類,就必須建立一個新的實例變量。
  • 一個結束的操做不能被重啓。
  • 若是你取消了一個操做,它不會立刻就發生。它會在將來的某個時候某人在「main」函數中明確地檢查isCancelled == YES 時被取消掉;不然,操做會一直執行到完成爲止。(見上圖)
  • 一個操做是否成功地完成,失敗了,或者是被取消了,isFinished的值總會被設置爲YES。因此千萬不要以爲isFinished == YES就表示全部的事情都順利完成了 — 特別的,若是你在代碼裏面有從屬性(dependencies),就要更加註意!

 

NSOperationQueue API

查看當前併發操做的全部任務:

 

掛起與恢復操做:

This method suspends or resumes the execution of operations. Suspending a queue prevents that queue from starting additional operations. In other words, operations that are in the queue (or added to the queue later) and are not yet executing are prevented from starting until the queue is resumed. Suspending a queue does not stop operations that are already running.

這個方法會掛起或者恢復一個執行的任務.掛起一個隊列能夠阻止該隊列中沒有開始的任務.換句話說,在任務隊列中尚未開始執行的任務是會被掛起的,直到這個掛起操做被恢復.掛起一個隊列不會讓一個已經執行的任務中止哦,親.

 

取消全部操做:

要取消一個隊列中的全部操做,你只要簡單的調用「cancelAllOperations」方法便可。還記得以前提醒過常常檢查NSOperation中的isCancelled屬性嗎?
緣由是「cancelAllOperations」並無作太多的工做,他只是對隊列中的每個操做調用「cancel」方法 — 這並無起很大做用!:] 若是一個操做並無開始,而後你對它調用「cancel」方法,操做會被取消,並從隊列中移除。然而,若是一個操做已經在執行了,這就要由單獨的操做去識 別撤銷(經過檢查isCancelled屬性)而後中止它所作的工做。

 

簡單的block形式的隊列任務:

 

以上就基本上講完了怎麼使用NSOperation以及NSOperationQueue了,親.

相關文章
相關標籤/搜索