【问题标题】:Core Data -existingObjectWithID:error: causes error 133000核心数据 -existingObjectWithID:error: 导致错误 133000
【发布时间】:2012-01-28 01:49:32
【问题描述】:

我的应用程序使用 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.

在我的情况下这是不正确的:该对象存在。事实上,如果我用NSFetchRequest 遍历该Collection 实体的所有实例,我会在其中找到它,而它的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 的现实场景是什么?

感谢您的启发。

【问题讨论】:

  • 你有没有想过这个问题?我遇到了同样的问题,我的对象肯定在那里并且保存操作正在运行,但它只是偶尔发生。

标签: cocoa core-data fault


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 不是这样:当我使用-objectWithID: 时,我得到了正确的对象(正如我所写的):我可以使用它,访问它的属性、它的关系、一切。事实上,它之前创建的上下文被保存了。然而,-existingObjectWithID:error: 仍然失败并出现错误 133000。
    • 听起来很奇怪。两个上下文是否共享相同的 NSPersistentStoreCoordinator?
    • 我通过对 managedObjectContext 进行重置“解决了”这个问题。当然不理想,所以我期待听到其他解决方案:-)
    • “对 managedObjectContext 进行重置”是什么意思?
    【解决方案3】:

    NSManagedObjectReferentialIntegrityError = 133000

    NSManagedObjectReferentialIntegrityError 错误代码表示 尝试触发指向不存在的对象的故障。这 store 可以访问,但是故障对应的对象不能访问 被发现。适用于 Mac OS X v10.4 及更高版本。宣布于 CoreDataErrors.h.

    看到这个documentation

    This tutorial 可能对你有帮助。

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

        childManagedObjectContext.parent = managedObjectContext

        【讨论】:

          猜你喜欢
          • 2012-04-04
          • 1970-01-01
          • 2020-10-26
          • 2012-08-01
          • 2018-09-02
          • 2017-02-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多