在子 NSManagedObjectContext 中使用 NSManagedObject 而不是其父

Posted

技术标签:

【中文标题】在子 NSManagedObjectContext 中使用 NSManagedObject 而不是其父【英文标题】:Use NSManagedObject in child NSManagedObjectContext instead of its parent 【发布时间】:2015-10-21 21:53:39 【问题描述】:

我有两个 MOC:第一个是根上下文。当我保存此上下文时,更改将保存到持久存储协调器。第二个 MOC 将第一个 MOC 作为父级。当我保存第二个 MOC 时,我还必须保存第一个 MOC,以便将第二个 MOC 中的更改保存到持久存储协调器。

我使用第二个 MOC 让用户编辑一个对象。他可以保存或取消更改。当他保存更改时,所有 MOC 都会被保存。当他取消更改时,我致电第二个 MOC 的rollback()

不幸的是,该对象来自第一个 MOC。这意味着,我执行 NSFetchRequest 来获取第一个 MOC 上的对象。然后我创建了第二个 MOC,用户可以在其中编辑对象。但是有一个问题:当第二个 MOC 应该改变一些东西时,例如删除一个包含在用户想要编辑的原始对象的数组中的对象,这是不可能的,因为 MOC 只能删除具有这个的对象MOC 作为上下文。但是该对象是在第一个 MOC 中获取的。

这就是为什么我需要在用户编辑对象之前以某种方式将对象从第一个 MOC“转移”到第二个 MOC。我不想再用 NSFetchRequest 什么的来获取对象,一定有更好的方法……

这可能吗?或者您是否建议完全不同,也许没有父上下文?

【问题讨论】:

【参考方案1】:

这就是NSManagedObjectobjectID 属性会派上用场的地方。

向对象询问其 ID

let objectID = myManagedObject.objectID

向子上下文询问具有该 ID 的托管对象

do 
    let childManagedObject = try childContext.existingObjectWithID(objectID)
    print("\(newObject)")
 catch 


【讨论】:

谢谢,这就是我要找的。你认为使用objectID 是正确的方法吗?或者我不应该使用父上下文来解决这个问题吗?【参考方案2】:

我认为您可能会因此而耽误您的时间。除非完全有必要保存提议的更改,否则没有理由为此有两个上下文。有多种方法可以处理临时数据,您可以使用这些方法将实际记录与不存储两次的实际记录进行比较。

为什么不直接创建 NSManagedObject 的副本并通过比较处理信息更正,或者干脆将原始 NSManagedObject 替换为副本的数据,然后保存?我个人更喜欢这种设置,因为我所要做的就是在需要更新时比较各个属性。

当需要完全更新时,您可以直接在一个 NSManagedObject 上工作而不必担心副本,因为无论如何您可能会替换整个东西。就像我说的,还有其他处理方法,但如果您绝对有必要同时拥有这两种上下文,则查找每个属性值与替换值的比较,然后简单地将其保存在父上下文中。

【讨论】:

我要编辑的对象是一个非常复杂的类,具有不同的关系等。我认为复制对象不是我想要的。当然,我可以直接在 NSManagedObject 上工作,但在编辑时可能会更改其他对象。当我想保存它们时,编辑的对象也会被保存。这是不可接受的,因为用户可能想要取消编辑。难道没有其他方法可以实现这一点,而不必寻找每个属性的比较? 这绝对是冲突最少的选项。两个对象,一个当前保存,一个提议更改,唯一改变不同之处的唯一方法是比较它们,除非你想处理你的对象可能在一个更多的字典设置中,这将允许你只存储值的键值对需要,但这将涉及像我说的那样拥有更多对象的字典结构。我知道您的对象很复杂,但是如果您在其中和内部包含的所有对象都设置正确,那么复制应该不难。

以上是关于在子 NSManagedObjectContext 中使用 NSManagedObject 而不是其父的主要内容,如果未能解决你的问题,请参考以下文章

父 NSManagedObjectContext 在子保存后没有变化,但仅在发布模式下(在调试模式下工作)

在子上下文中保存核心数据不起作用

保存后在子上下文中创建的新对象在父上下文中不存在

父/子 NSManagedObjectContext 不起作用

NSManagedObjectContext:自动更新与否?

NSManagedObjectContext:撤消保存操作?