核心数据-existingObjectWithID:错误:导致错误133000

我的应用程序使用核心数据(有一些魔法logging的帮助),并使用NSOperation相当严重的multithreading。

当然,我非常小心只能在线程/操作之间传递NSManagedObjectID

现在,为了回到操作中相应的托pipe对象,我使用-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. 

在我的情况下,这是不正确的:这个对象是存在的。 实际上,如果我用NSFetchRequest迭代那个Collection实体的所有实例,我发现它在其中,它的NSManagedObjectID正是我传递给-existingObjectWithID:error:

而且,如果我使用-objectWithID:取而代之,我得到一个正确的对象就好了。

所以有一些我错过了。 以下是一些其他意见/问题:

  • “不存在的客体”:这句话中“存在”的含义是什么? “存在”在哪里? 在那个时候,它在我的核心数据存储中绝对“存在”。
  • “找不到对应的对象”:那句话中“find”的含义是什么? “find”在哪里? 这一点在我的核心数据存储中肯定会“find”。

所以也许我错过了什么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一个现实的情况?

感谢任何启示。

问题是您传递的NSManagedObjectID是临时的。 你可以通过调用NSManagedObjectIDisTemporaryID方法来检查它。 从文档:

返回一个布尔值,指示接收者是否是临时的。

大多数对象ID返回NO。 插入到托pipe对象上下文中的新对象被分配一个临时ID,一旦该对象被保存到持久性存储中,该临时ID将被replace为永久的ID。

您应该首先将您的更改保存到持久性存储中 ,然后才能将永久ID传递给其他上下文。

在使用多个上下文时,需要确保在将上下文A中的托pipe对象ID传递到另一个上下文B之前保存上下文A.只有在保存完成后,才能从上下文B访问该对象。

-objectWithID:将始终返回一个非零对象,但是如果商店中没有后备对象,则会在开始使用它时引发exception。 -existingObjectWithID:error:实际上会运行一些SQL,并执行I / O如果该对象尚未注册使用的上下文。

NSManagedObjectReferentialIntegrityError = 133000

NSManagedObjectReferentialIntegrityError错误代码表示试图触发指向不存在的对象的错误。 商店是可访问的,但是找不到对应的对象。 适用于Mac OS X v10.4及更高版本。 在CoreDataErrors.h中声明。

请参阅此文档 。

本教程可能对您有所帮助。

所以可能的原因是你正试图获取不存在的对象。 当您尝试为不存在的对象创buildobjectid时,通常会发生这种情况。 objectid将被返回给你,当试图获得这个objectId的对象时,你抛出了这个exception。

我在处理NSManagedObjectContextDidSave通知时发现了它们。 许多另一个上下文已经删除的对象无法被提取,因为(Duh!)它们被删除了! 但是,一些被删除的对象显示得很好,就像我在当前上下文中已经出错的对象一样。

你可能会遇到类似的问题 – 当你迭代商店时你可以find的对象在被删除之前可能已经进入该上下文,并且你没有将更改合并回上下文,或者尚未完全合并。