2011-02-24 36 views
-1

我在通過外部線程保存一堆NSManagedObjects時遇到了衝突。對於初學者,我可以告訴你以下幾點:解決與多個線程,關係和指針的NSManagedObject衝突

  1. 我爲每個線程使用一個單獨的MOC。
  2. MOC共享相同的持久性存儲協調器。
  3. 外部線程很可能正在修改我保存的一條或多條記錄。

好的,所以這樣做,這就是我正在做的。

在我的外部線程中,我正在做一些計算並更新一堆管理對象中的單個值。我通過在主持久存儲庫中查找對象,修改單個小數值屬性,然後一次調用保存在堆中。

在此期間,我相信主線程正在做一些自己的更新。

當我的外部線程在託管的對象上下文上做了大的保存時,我得到一個拋出的異常,說明了大量的衝突。所有的衝突似乎都集中在每條記錄上的單一關係上。儘管持久性存儲中的託管對象和我的外部線程共享此關係的相同ObjectID,但它們不共享相同的指針。基於我所看到的,這是我的NSMergeConflict調試輸出中的對象之間唯一不同的東西。

這對我來說很有意義,爲什麼這兩個對象與不同的指針有關係 - 它們在不同的線程中。然而,正如我從Apple的文檔中瞭解的,首次從持久性存儲中檢索對象時緩存的唯一內容是全局ID。所以,有人會認爲當我在外部線程MOC上運行保存時,它會比較ObjectIDs,看到它們是相同的,並讓它通過。

那麼,誰能告訴我爲什麼我會發生衝突?

回答

0

不幸的是,它似乎好像這個錯誤實際上是由其他的東西引起的 - 我不應該在同一時間多次調用導致錯誤的操作。儘管這並沒有回答最初的問題,爲什麼指針在衝突中很重要,更新我的代碼以防止這種情況已經解決了我的問題。

2

每在併發性的核心數據章核心數據編程指南的文件,推薦的配置是上下文共享相同的持久性存儲協調,不一樣的持久性存儲。

此外,部分修訂其他線程使用通知同一章的狀態如果您要跟蹤與NSManagedObjectContextDidSaveNotification更新,那麼你發送-mergeChangesFromContextDidSaveNotification主線程的上下文,因此它可以合併變化。但是,如果您使用NSManagedObjectContextDidChangeNotification進行跟蹤,則外部線程應將修改對象的對象ID發送給主線程,然後主線程將發送-refreshObject:mergeChanges:到每個修改對象的上下文。

實際上,您應該知道主線程是否也通過其控制器執行更新,並以類似的方式傳播其更改,但方向相反。

+0

感謝您的回覆。我會研究如何使用持久性商店協調員 - 我還沒有看過。至於通知,我使用NSManagedObjectContextDidSaveNotification在主線程上偵聽更新併合並它們。不幸的是,它是拋出錯誤的外部線程,雖然我可以在該方向添加合併,但我特別想知道爲什麼當除了關係的指針(而不是ObjectID)之外似乎沒有字段被更新時會有衝突。 – 2011-02-24 04:48:59

+0

我剛剛檢查過 - 我不僅使用相同的持久存儲,而且還使用相同的持久存儲協調器,因此在那裏應該沒有問題。 – 2011-02-24 04:53:38

+1

確實。你如何更新主線程上下文中的對象? – Huperniketes 2011-02-24 05:02:49

0

您需要讓所有上下文都在任何進行更改的上下文中監聽NSManagedObjectContextDidSaveNotification。否則,只有前端上下文才會意識到後臺線程所做的更改,但後臺上下文不會知道前端線程上的更改。因此,如果您有三個線程和三個上下文,每個線程都進行更改,則所有三個上下文都必須註冊另外兩個上下文的通知。

+0

感謝您的幫助。我知道這可能有助於解決衝突的發生,但是,我的主要問題是爲什麼第一個衝突。不幸的是,正如你在上面我的評論中看到的那樣,我們可能永遠不會知道真正的答案。不管怎樣,謝謝你! – 2011-02-26 04:04:39