2

我已經閱讀了大量有關後臺核心數據流程的博客,但我並沒有接近理解如何最好地管理許多BG核心數據任務一次全部觸發並通知返回到未定義時間的主線程MOC。多個NSManagedObjectContexts - 防止競爭條件和死鎖

我知道你應該通過使用[context performBlock我得到了一些不錯的異步任務完成沿訂閱NSManagedObjectContextDidSaveNotification有1 NSManagedObjectContextNSThread和。

這就是說,我跑了很多任務異步,我不100%知道什麼時候有人會重疊,我在的形式觀察比賽條件...

  • BG MOC 1襯托它的任務
  • BG商務部2上的任務
  • BG MOC 2分完成任務,並保存發送通知
  • BG MOC 1分完成任務,然後擦去BG MOC 2S襯托改變

我的整體問題是如何解決多個MOC中的競賽條件?

  1. 如果正確的行爲是讓每個線程1個MOC ..我可以創建一個NSThread伊娃並把我的核心數據的工作推上了嗎?這樣我可以有一個與自身同步的MOC?

  2. 我讀過一個NSLock可能是避免某些代碼被同時從多個線程訪問的解決方案..但我不知道我應該鎖定什麼?保存上下文方法?持久存儲(似乎使多線程毫無意義)?

  3. 最後,我可以標記/編號/命名我的MOCs嗎?這樣,如果我知道其他任務正在運行,我可以存儲通知並按照實例化的順序處理它們以確保沒有數據被覆蓋?建議每個線程

回答

14
  1. 一個MOC。雖然有例外,但通用規則仍然成立。不要創建NSThread對象。不要。太痛苦了。而是使用塊或NSOperation實例。他們更容易打擾和保護你免受很多痛苦。

  2. 請勿將鎖與核心數據一起使用。核心數據在正確使用時會自行鎖定,如果您在周圍扔鎖,會導致問題。理想情況下,你應該從來沒有需要調用現代Objective-C鎖定自己。

  3. 除了對他們進行ivar或財產引用之外,您不能命名MOC。你不應該也需要。

做多線程核心數據最徹底的方法如下:

  • 你有一個主線程/ UI MOC。這是你的唯一真理來源。您的UI從它饋送並寫入它。
  • 任何後臺進程都是在NSOperation或類似的構造中完成的。您在此構造內部創建MOC,並且它是主環境的上下文子環境
  • 保存孩子時,更改將合併到父級(這是UI MOC)。
  • 設置適合您的主要MOC的合併策略。如果你認爲你需要針對不同情況採取不同的政策,那麼你應該重新評估自己如何做事。

理想情況下,每個後臺進程應該是一個獨立運行的數據倉庫,不會與其他進程衝突。如果遇到碰撞,那麼這是一個需要在業務邏輯中解決的合併問題。

如果您有兩個後臺操作要碰到同一條數據的情況,那麼您應該按順序運行它們,而不是並行運行。並行編輯相同的數據是等待發生的痛苦,不要這樣做。

您可以通過使用NSOperationQueue實例來控制事物是順序的還是並行的。

遵循這些規則,你將不會有競爭條件或死鎖。

+0

很好的回答,非常感謝。我沒有在我的實現中使用'NSOperation' /'NSOperationQueue',所以我會從那裏開始。很高興能在我所有的狡猾想法上得到堅定的回答。 – Magoo 2014-12-03 08:27:47

+1

「NSOperation或類似的結構。你創建一個MOC而不是這個結構」應該是「在這個結構中」嗎? – 2014-12-03 10:13:50

+0

謝謝@IanDundas,更正。 – 2014-12-03 15:26:23