在上下文之间移动对象时 iOS coredata objectWithID 中的错误

Posted

技术标签:

【中文标题】在上下文之间移动对象时 iOS coredata objectWithID 中的错误【英文标题】:Bug in iOS coredata objectWithID when moving objects between contexts 【发布时间】:2013-01-11 20:16:49 【问题描述】:

我正在使用核心数据观察 ios 中的一个奇怪错误。 基本上,我的设置如下 - 有 2 个 NSManagedObjectContexts,tempContextmainContext。 我使用tempContext 作为临时“便签本”来创建和编辑实体,当我想保存它们时,我将其移动到mainContext 进行保存。 请注意,mainContext 不是 tempContext 的父级。

移动发生如下-

[1] newEntity.property1 = @"SomeProperty";
    newEntity.managedObjectContext // this is tempContext currently
[2] saveEntityInTempContext
[3] newEntity = (Entity *)[mainContext objectWithID:newEntity.objectID];
[4] [mainContext insertObject:newEntity];

现在,在插入[4] 之后,如果我检查newEntity.property1,它被设置为nil。 但是,如果我在 [3] 之后检查属性,然后在 [4] 之后检查该属性,它会正确显示为“SomeProperty”。我不明白强制故障在这里应该如何产生影响。

我的目标只是将实体从一个上下文移动到另一个上下文。

【问题讨论】:

[mainContext objectWithID:newEntity.objectID] 从主上下文返回一个对象。我认为没有必要(并且可能是错误的)在该对象上调用 insertObject,它已经被插入。 你最初是如何创建newEntity 的?是否已经插入tempContext?另外,执行此代码时是否已将更改保存在 tempContext 上? @TomHarrington 是的,newEntity 已经插入到 ``tempContext``` 中,步骤[2] 表示实体保存在 tempContext 中。 @MartinR 即使没有插入,问题仍然存在(显式故障和非故障实体之间的不同行为)。 【参考方案1】:

我不确定直接原因是什么,但这几乎可以肯定是不必要的步骤的奇怪副作用,实际上没有任何意义。我有点惊讶你在最后一步没有得到异常。

具体来说,步骤#4 是完全没有必要的。完成第 3 步后,您将拥有一个从 mainContext 加载的实例。那时你不需要做更多的事情。为您刚刚从同一托管对象上下文中查找的对象调用 insertObject 是没有意义的。

假设tempContextmainContext 使用相同的持久化存储协调器,则此对象的生命周期按照您的步骤进行如下:

    newEntity 已创建但未保存。 tempContext 知道 newEntity,但数据存储不知道(当然 mainContext 也不知道)。 保存后,数据存储有newEntity的记录。 newEntity 的对象 ID 更改为永久值。 作为objectWithID: 调用的结果,newEntity 的实例被替换为通过mainContext 查找的另一个实例。它的属性与您在第 1 步中创建并在第 2 步中保存到数据存储区的属性相匹配,因为它们是从数据存储区加载的。 调用insertObject 毫无用处——因为您在步骤3 中获得的新newEntity 是从mainContext 查找的,这意味着mainContext 已经知道它。这是我预期的例外。没有发生异常,但调用仍然没有意义。

所以,我将放弃第 4 步并完成它。

【讨论】:

谢谢,这条线帮助我解决了这个问题! "调用,newEntity 的实例被替换为通过"查找的不同实例"

以上是关于在上下文之间移动对象时 iOS coredata objectWithID 中的错误的主要内容,如果未能解决你的问题,请参考以下文章

CoreData 对象未在屏幕之间保存

非法尝试在不同上下文中的对象之间建立关系“清单”

CoreData 和 NSManagedObjectContext

IOS手动添加CoreData

Core Data - 如何在不同的上下文中建立两个对象之间的关系

在多线程上下文中,在托管对象上设置属性时,CoreData 阻塞