2011-12-26 67 views
38

我的應用程序使用核心數據(有一些魔法記錄的幫助),並且使用NSOperation進行了相當嚴重的多線程操作。核心數據-existingObjectWithID:錯誤:導致錯誤133000

當然,我非常小心只能在線程/操作之間傳遞NSManagedObjectID

現在,要回在操作相應的管理對象,我用-existingObjectWithID:error:這樣的:

Collection *owner = (Collection *)[localContext existingObjectWithID:self.containerId error:&error]; 

但我得到的回覆是零和error說,這是一個錯誤#13300:NSManagedObjectReferentialIntegrityError

這裏是什麼文件說,關於這個錯誤:

NSManagedObjectReferentialIntegrityError 
Error code to denote an attempt to fire a fault pointing to an object that does not exist. 
The store is accessible, but the object corresponding to the fault cannot be found. 

這是不是在我的情況屬實:該對象存在。事實上,如果我遍歷Collection實體的所有實例與NSFetchRequest,我發現其中,它的NSManagedObjectID正是我傳遞給-existingObjectWithID:error:

此外,如果我使用-objectWithID:來替代,我會得到一個正確的對象。

所以有一些我失蹤了。這裏有一些額外的觀察/問題:

  • 「一個不存在的對象」:那句話中「存在」的含義是什麼? 「存在」在哪裏?當然,它在我的核心數據存儲中是「存在」的。
  • 「無法找到與錯誤對應的對象」:該句子中「找到」的含義是什麼? 「找到」在哪裏?這一點在我的Core Data商店中肯定會「找到」。

所以也許我缺少關於什麼existingObjectWithID:error:做一些事情?該文檔說:

If there is a managed object with the given ID already registered in the context, that object is returned directly; otherwise the corresponding object is faulted into the context. 
[...] 
Unlike objectWithID:, this method never returns a fault. 

這不會幫助我的問題。我不介意讓我的對象完全失敗,而不是一個錯誤。實際上,當我訪問對象屬性時,其中的任何錯誤都會在下一個代碼行中觸發。

  • 什麼是導致NSManagedObjectReferentialIntegrityError的現實情況?

感謝您的任何啓示。

+2

你有沒有想過這個?我遇到同樣的問題,我的對象肯定在那裏,保存操作正在運行,但它只是偶爾發生。 – Adam 2013-04-16 06:38:04

回答

36

問題是您通過的NSManagedObjectID是暫時的。您可以致電NSManagedObjectIDisTemporaryID方法進行檢查。從文檔:

Returns a Boolean value that indicates whether the receiver is temporary.

Most object IDs return NO. New objects inserted into a managed object context are assigned a temporary ID which is replaced with a permanent one once the object gets saved to a persistent store.

你應該先保存更改到持久性存儲,只有獲得永久ID傳遞到其他方面。

8

當您使用多個上下文時,需要確保在將上下文A中的託管對象ID傳遞到另一個上下文B之前保存上下文A.只有在保存完成後,該對象纔可以從上下文B訪問。

-objectWithID:將始終返回一個非零對象,但如果商店中沒有後備對象,它將在您開始使用它時引發異常。 -existingObjectWithID:error:實際上將運行一些SQL,並且如果該對象尚未使用它所使用的上下文註冊,則執行I/O操作。

+2

不是這樣的:當我使用'-objectWithID:'時,我得到了正確的對象(正如我寫的):我可以使用它,訪問它的屬性,它的關係,一切。事實上,之前創建的環境得到保存。然而,'-existingObjectWithID:error:'仍然失敗,錯誤133000. – 2011-12-27 16:53:47

+0

聽起來真的很奇怪。兩個上下文是否共享相同的NSPersistentStoreCoordinator? – 2011-12-28 13:07:04

+1

我通過在managedObjectContext上執行重置來「解決」這個問題。肯定不理想,所以我期待聽到其他解決方案:-) – niklassaers 2012-02-13 14:30:49

2

NSManagedObjectReferentialIntegrityError = 133000

NSManagedObjectReferentialIntegrityError Error code to denote an attempt to fire a fault pointing to an object that does not exist. The store is accessible, but the object corresponding to the fault cannot be found. Available in Mac OS X v10.4 and later. Declared in CoreDataErrors.h.

看到這個documentation

This tutorial可能對您有所幫助。

所以可能的原因是你試圖獲取不存在的對象。當你嘗試爲一個不存在的對象創建一個objectid時,通常會發生這種情況。 objectid將返回給您,當嘗試使用此objectId獲取對象時,會引發此異常。

0

我在處理NSManagedObjectContextDidSave通知時發現了它們。許多其他上下文已刪除的對象無法被提取,因爲(Duh!)它們已被刪除!但是,一些已刪除的對象顯示得很好,就像我在當前上下文中已經出錯的對象一樣。

您可能會遇到類似的問題 - 在迭代存儲時,您可以找到的對象在被刪除之前可能已經進入該上下文,並且您沒有將更改合併回該上下文,或者沒有相當尚未合併。