簡體   English   中英

iphone - 我應該使用NSOperationQueue和NSOperation而不是NSThread嗎?

[英]iphone - Should I use NSOperationQueue and NSOperation instead of NSThread?

我正面臨着我的應用程序的設計問題。


基本上,以下是我在我的應用程序中要做的事情。

單個任務是這樣的:

  1. 從底層CoreData數據庫中讀取自定義對象
  2. 從網址下載json
  3. 解析json以更新自定義對象或創建一個新對象(解析可能需要1 - 3秒,大數據)
  4. 分析自定義對象(將涉及一些計算,可能需要1 - 5秒)
  5. 將自定義對象保存到CoreData數據庫中。

可能會同時執行許多任務。

一個任務中的步驟顯然是ordered (即,沒有第2步下載json,步驟3不能繼續),但它們也可以是discrete 我的意思是,例如,task2的第4步可以在task1的第3步之前執行(如果task2的下載速度比task1的更快)

任務有優先事項。 用戶可以啟動具有更高優先級的任務,因此將嘗試在所有其他任務之前執行所有任務的步驟。


我希望UI能夠盡可能地響應。

所以我打算創建一個優先級最低的NSThread。

我在該線程中放置了一個自定義優先級事件隊列。 任務的每一步都成為一個事件(工作單位)。 因此,例如,下載json的步驟1成為事件。 下載后,該事件會為步驟3生成另一個事件並將其放入隊列中。 每個事件都有自己的優先級設置。


現在我看到這篇文章: 並發和應用程序設計 Apple建議我們Move Away from Threads並使用GCDNSOperation

我發現NSOperation非常符合我的草案設計。 但我有以下問題:

  • 考慮到iPhone / iPad cpu內核,我應該只使用一個NSOperationQueue還是創建多個?
  • NSOperationQueue或NSOperation是否以最低線程優先級執行? 執行是否會影響UI響應(我關心因為步驟涉及計算)?
  • 我可以從另一個生成NSOpeartion並將其放入隊列嗎? 我在NSOperation中沒有看到隊列屬性,我怎么知道隊列?
  • 如何將NSOperationQueue與CoreData合作? 每次訪問CoreData時,我應該創建一個新的上下文嗎? 這會貴嗎?
  • 任務的每一步都成為NSOperation,這個設計是否正確?

謝謝

考慮到iPhone / iPad cpu內核,我應該只使用一個NSOperationQueue還是創建多個?

對於大多數情況,兩個(CPU,網絡+ I / O)或三個(CPU,網絡,I / O) 串行隊列應該可以很好地工作,以保持應用程序的響應性,並使您的程序流按照它們的約束進行工作。 當然,您可能會發現另一種組合/配方適用於您的特定工作分配。

NSOperationQueue或NSOperation是否以最低線程優先級執行? 執行是否會影響UI響應(我關心因為步驟涉及計算)?

不是默認的。 請參閱-[NSOperation setThreadPriority:]如果要降低優先級。

我可以從另一個生成NSOpeartion並將其放入隊列嗎? 我在NSOperation中沒有看到隊列屬性,我怎么知道隊列?

當然。 如果您使用我概述的串行方法,找到正確的隊列很容易 - 或者您可以使用ivar。

如何將NSOperationQueue與CoreData合作? 每次訪問CoreData時,我應該創建一個新的上下文嗎? 這會貴嗎?

(沒有意見)

任務的每一步都成為NSOperation,這個設計是否正確?

是的 - 將您的隊列划分為它所綁定的資源是一個好主意。

  • 通過外觀,NSOperationQueue就是你所追求的。 您可以設置要同時運行的並發操作數。 如果使用多個NSOperation,它們將同時運行...除非您自己處理隊列,這與使用NSOperationQueue相同

  • 線程優先級......我不確定你的意思,但在iOS中,UI繪圖,事件和用戶交互都在主線程上運行。 如果你在后台線程上運行東西,那么無論你運行多么復雜或繁重的操作,界面仍然會響應

  • 生成和處理操作你應該在主線程上執行它,因為它不需要任何時間,你只需在后台線程中運行它們,這樣你的主線程就不會被鎖定

  • CoreData,我沒有特別使用它,但到目前為止每個Core~我使用它在后台線程上工作得很好,所以它應該不是問題

  • 就設計而言,這只是一個觀點......對於我來說,每個任務都有一個NSOperation,並讓它處理所有步驟。 如果您想提供一些反饋或繼續進行其他下載或其他操作,也可以在步驟完成時編寫回調

多線程計算的影響不會因為你使用NSThread而不是NSOperation而有所不同。 但請記住,當前的iOS設備必須使用雙核處理器。

你遇到的一些問題不是很具體。 您可能想要也可能不想使用多個NSOperationQueue。 這一切都取決於你想要如何接近它。 如果您有不同的NSOperation子類或不同的NSBlockOperations,則可以使用優先級管理執行順序,或者您可能希望為不同類型的操作(尤其是在使用串行隊列時)使用不同的隊列。 我個人更喜歡在處理相同類型的操作時使用1個操作隊列,並且當操作不相關/可靠時具有不同的操作隊列。 這使我可以靈活地根據發生的事情取消和停止隊列中的操作(網絡丟棄,應用程序轉到后台)。

我從來沒有找到一個很好的理由根據當前操作執行期間發生的事情添加操作。 如果需要這樣做,可以使用NSOperationQueue的類方法currentQueue,它將為您提供當前操作正在運行的操作隊列。

如果您使用NSOperation進行核心數據工作,我建議為每個特定操作創建一個上下文。 確保初始化main方法中的上下文,因為這是您在NSOperation后台執行的正確線程上的位置。

您不一定需要為每個任務都有一個NSOperation對象。 您可以下載數據並在NSOperation中解析它。 您還可以抽象地進行數據下載,並使用NSOperation的完成塊屬性對下載的內容進行數據處理。 這將允許您使用相同的對象來獲取數據,但具有不同的數據操作。

我的建議是閱讀NSOperation,NSBlockOperation和NSOperationQueue的文檔。 檢查當前的設計,了解如何使用當前項目調整這些類。 我強烈建議你去NSOperation家族而不是NSThread家庭。

祝好運。

只是為了添加@ justin的答案

如何將NSOperationQueue與CoreData合作? 每次訪問CoreData時,我應該創建一個新的上下文嗎? 這會貴嗎?

NSOperation與Core Data一起使用時應該非常小心。
什么,你總是有要記住的是,如果你想在一個單獨的線程運行CoreData操作,你必須創建一個新NSManagedObjectContext該線程,共享主要的托管對象上下文持續性商店協調員(“主” MOC是一個在應用程序委托)。

此外, 從該線程創建該線程的新托管對象上下文非常重要 因此,如果您計划在NSOperation使用Core Data, NSOperation確保在NSOperation的main方法而不是init初始化新的MOC。

是關於核心數據和線程的非常好的文章

使用GCD - 它比NS *更好的框架

將所有CoreData訪問權保留在一個隊列中,並在例程結束時將dispatch_async保存到CoreData數據庫。

如果您有開發者帳戶,請查看此WWDC視頻: https//developer.apple.com/videos/wwdc/2012/? id = 712

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM