1. 程式人生 > 實用技巧 >使用NSOperation以及NSOperationQueue 多執行緒併發處理。

使用NSOperation以及NSOperationQueue 多執行緒併發處理。

>>> hot3.png

http://www.cnblogs.com/YouXianMing/p/3707403.html?utm_source=tuicool&utm_medium=referral

NSOperation vs. Grand Central Dispatch (GCD)

在Mac OS X v10.6和iOS4之前,NSOperation 與 NSOperationQueue 不同於GCD,他們使用了完全不同的機制。

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

以下是對兩者的快速比較,它會幫助你決定何時何地去使用GCD或者NSOperation和NSOperationQueue;

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

NSOperation API

NSOperation 類有一個相當簡短的宣告。要定製一個操作,可以遵循以下步驟:

  1. 繼承NSOperation類
  2. 重寫“main”方法
  3. 在“main”方法中建立一個“autoreleasepool”
  4. 將你的程式碼放在“autoreleasepool”中(ARC中也需要放在autoreleasepool中,這是為了相容MRC程式碼)

為了你能夠測試程式碼,請新建一個類,繼承自NSOperation,寫成如下的形式:

之後再進行操作:

注意,只有將一個任務新增進了隊列當中,這個任務才會被執行.

以下程式碼是併發執行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了,親.

轉載於:https://my.oschina.net/huqiji/blog/870585