我的应用程序使用Core Data(在Magical Record的帮助下)并使用NSOperation
进行了大量多线程。
当然,我非常小心,只能在线程/操作之间传递NSManagedObjectID
。
现在,为了回到操作中相应的托管对象,我使用-existingObjectWithID:error:
:
Collection *owner = (Collection *)[localContext existingObjectWithID:self.containerId error:&error];
但我得到的是nil,而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:
,我会得到一个正确的对象。
所以我有些遗漏。以下是一些其他观察/问题:
所以也许我错过了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
?感谢任何启发。
答案 0 :(得分:38)
问题是你传递的NSManagedObjectID
是暂时的。您可以通过调用NSManagedObjectID
的{{1}}方法进行检查。来自docs:
返回一个布尔值,指示是否 接收器是暂时的。
大多数对象ID返回NO。插入新对象 为托管对象上下文分配一个替换的临时ID 一旦对象被保存到持久存储中,就会使用永久存储。
您应首先将更改保存到持久存储,然后才能获取永久ID以传递到其他上下文。
答案 1 :(得分:8)
当您使用多个上下文时,您需要确保在将托管对象ID从上下文A传递到另一个上下文B之前保存上下文A.只有在保存完成后才能从上下文B访问该对象。
-objectWithID:
将始终返回一个非nil对象,但如果商店中没有后备对象,则一旦开始使用它就会抛出异常。如果该对象尚未在其使用的上下文中注册,-existingObjectWithID:error:
实际上将运行一些SQL并执行I / O.
答案 2 :(得分:2)
NSManagedObjectReferentialIntegrityError = 133000
NSManagedObjectReferentialIntegrityError用于表示的错误代码 尝试触发指向不存在的对象的故障。该 存储是可访问的,但对应于故障的对象不能 被发现。适用于Mac OS X v10.4及更高版本。宣布于 CoreDataErrors.h。
请参阅此documentation。
This tutorial可能会对您有所帮助。
所以可能的原因是你试图获取不存在的对象。当您尝试为非现有对象创建objectid时,通常会发生这种情况。 objectid将返回给您,当尝试使用此objectId获取对象时,您将抛出此异常。
答案 3 :(得分:0)
我在处理NSManagedObjectContextDidSave通知时找到了它们。其他上下文删除的许多对象都无法获取,因为(Duh!)它们已被删除!然而,一些被删除的对象显示得很好,就像我在当前环境中已经出现故障一样。
您可能会遇到类似的问题 - 您在迭代商店时可以找到的对象可能在被删除之前已经被置于该上下文中,并且您要么没有将更改合并回该上下文,要么只是避难所。尚未合并。
答案 4 :(得分:0)
即使objectID不是临时的,我也遇到了这个问题。 这是因为我愚蠢地忘记了将父代设置为子代MOC。
childManagedObjectContext.parent = managedObjectContext