40

我的应用程序使用 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什么?

感谢您的任何启发。

4

5 回答 5

40

问题是NSManagedObjectID你通过是暂时的。您可以通过调用NSManagedObjectID'sisTemporaryID方法来检查它。来自文档:

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

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

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

于 2014-02-20T14:21:59.623 回答
8

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

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

于 2011-12-27T16:28:10.890 回答
2

NSManagedObjectReferentialIntegrityError = 133000

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

请参阅本文档

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

所以可能的原因是你试图获取不存在的对象。当您尝试为不存在的对象创建 objectid 时,通常会发生这种情况。objectid 将返回给您,当尝试使用此 objectId 获取对象时,您会抛出此异常。

于 2012-02-15T10:00:36.353 回答
0

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

您可能会遇到类似的问题 - 您在迭代存储时可以找到的对象在被删除之前可能已经错误地进入该上下文,并且您没有将更改合并回该上下文,或者尚未完全合并。

于 2014-10-17T23:03:19.267 回答
0

我遇到了这个问题,即使 objectID 不是临时的。这是因为我愚蠢地忘记在子 MOC 上设置父级。

childManagedObjectContext.parent = managedObjectContext

于 2019-12-04T19:06:45.770 回答