2015-04-23 68 views
0

問:是否可以爲特定的核心數據保存禁用級聯刪除?

當你調用節省NSManagedObjectContext當有deletedObjects要處理的,它的工作的一個很好的協議跟蹤的關係,以確定哪些相關對象也需要被刪除。這是每次保存(即使在父/子上下文情況下),如果我知道我將通過父上下文保存,我希望能夠在第一次之後跳過對每個上下文的檢查,但是我找不到這樣做的機制。

背景:

這裏的情況,我有3個上下文:

  • C(B的子Context):後臺線程上下文做功A的
  • B(子Context ):一個主線程上下文,用於我的讀取結果控制器,UI訪問
  • A(子持久存儲):用於保存到磁盤的後臺線程上下文

我的對象圖是「Rich」,一些關係是針對具有100,000個項目的表。因此,刪除操作可以理解得很慢(級聯刪除會刪除一些刪除每個根對象的對象)。但是,當分析性能時,我意識到它實際上比所需要的要慢,在保存大部分CPU /時間用於解決圖形中的關係(試圖找出哪些相關對象也需要刪除)......並且它重複這個過程每次保存,即使我正在保存。
實施例保存過程:

  • 上下文C已1刪除對象
  • 保存上下文Ç - > B(約1工作的第二正在做跟蹤的關係)
  • 上下文C現在保存(0刪除對象),上下文B具有原始刪除對象,並且還需要刪除30個新的相關對象(31個對象)
  • 保存上下文B→A(約1秒的工作複查這些關係,這是我想跳過的工作)
  • 上下文B已保存(0個已刪除的對象),上下文A具有與B必須刪除的相同的31個對象
  • 保存上下文A - >持久存儲(在此處輕度工作,似乎此步驟不打擾重新檢查)

我試過了,並且調查了-[NSManagedObject validateForDeletion]-[NSManagedObjectContext processPendingChanges]沒有運氣。有什麼想法嗎?

+0

只是一個想法,可能是完全錯誤的。你有沒有嘗試清空你不想做任何工作的上下文,例如'reset'。當然,如果您不需要保存任何特定上下文已經產生的更改,那也只會是可以的。 –

回答

0

如果您使用多個核心數據堆棧並且您不介意進入一些中等複雜的代碼,應該可以選擇性地啓用/禁用刪除規則。你最終會得到多個管理對象上下文,其中一些有規則,有些則沒有。該協議是:

  • NSManagedObjectModel是可變的,當你第一次加載它,這樣你就可以修改代碼中的模型,只要你不做出改變,將使其與你的持久化存儲不相容(這需要移民)。
  • 模型兼容性僅由影響數據如何保存到持久性存儲的詳細信息確定。 刪除規則不包含,因此可以在不需要遷移的情況下對其進行修改。 (見什麼會影響兼容性[NSRelationshipDescription versionHash]的文檔。的NSManagedObjectModel
  • 實例是唯一可變的,直到您持久存儲使用它們,所以你必須加載任何數據之前進行更改。這意味着,如果你想在某些情況下,而不是在別人的刪除規則,你需要不同的實例NSManagedObjectModel

所以,如果你創建完全獨立的核心數據堆棧可以配置一個(的NSManagedObjectModelNSPersistentStoreCoordinator,等等,一切都不同實例)堆棧沒有這些刪除規則,但留在他人的地方,因爲刪除規則不會影響噸他模型散列,他們仍然是兼容的。

你不能用父/子託管對象上下文來做到這一點,因爲它們根據定義是同一個核心數據棧的一部分。

要刪除或更改刪除規則,您必須從您的NSManagedObjectModel實例開始。在模型中獲取entities,然後獲得relationshipsByName作爲您感興趣的實體。最後,在NSRelationshipDescription上,將deleteRule更改爲您想要的任何內容(在這種情況下可能爲NullifyDeleteRule)。

這將是一種複雜,但它應該工作。

另外,我想知道更多關於你的性能分析顯示的細節。

+0

嗯......不知道這是否適用於我的場景,因爲這裏的目標是能夠通過父/子上下文進行保存,而不會導致額外的關係查找開銷。但是,如果我可以篡改特定託管對象上下文的模型,它可能會起作用......然而,作爲第二個潛在問題,我認爲NullifyDeleteRule仍然會執行關係查找(至少在很多情況下)它可以取消(或刪除)關係行:(可能會更快一點,但我想完全跳過檢查 – BadPirate

+0

更改特定上下文的刪除規則在同一個堆棧中不起作用,因爲你必須在模型級別進行更改,另一種可能的方法是使用'NSNoActionDeleteRule',但是重寫'prepareForDeletion'來自己處理級聯效果 –

+0

這個最新的評論應該是你的答案。將它設置爲NSNoActionDeleteRule和然後在prepareForDeletion中自己管理刪除,確實可以選擇刪除計算的時間和頻率。 - 關於您的性能問題,在我們的我們正在使用自定義的SQL支持的NSIncrementalStore - 刪除中涉及的CPU的70%與「newFetchToManyRelationship」緊密相關,主要是因爲關係中的一個表具有大量記錄。 – BadPirate

相關問題