使用父 NSManagedObjectContext 时正确的工作流程

Posted

技术标签:

【中文标题】使用父 NSManagedObjectContext 时正确的工作流程【英文标题】:Correct workflow when using parent NSManagedObjectContext 【发布时间】:2016-10-06 17:44:41 【问题描述】:

我使用NSManagedObjectContext 链来表示可以回滚/取消的视图和操作的层次结构。 这是一个例子: 假设我有以下结构:

客户端列表(主 NSManagedObjectContext) 客户端详细信息(DetailContext - Parent = MainContext) 客户杂货(GroceryContext - Parent = DetailContext) 杂货支付(PaymentContext - 父级 = GroceryContext)

这样,我可以导航到杂货付款,进行更改,并在必要时取消,对于所有其他级别都是一样的。由于执行保存会将更改向上移动。到目前为止,这正在按预期工作。

我想了解的是执行以下操作的好方法:

在列表中打开客户端; 打开杂货店; 打开杂货店付款记录 添加交易

问题是,该事务也需要保存在后端,并保存在本地主上下文中,因为无论我在工作流的其余部分做什么,该事务都已完成。

我一直在做的是,在进行事务的情况下,将调用一系列委托,直到作为所有父上下文的根级别,并保存事务。但我想知道是否有更好的方法来做到这一点。因为即使交易完成,我也可能想取消在此过程中进行的一些其他更改。但是所有这些上下文都需要有一个已保存的事务上下文的更新对象,因为这是最终的。

请不要附和客户杂货的实际用例,这只是为了解释上下文的层次结构。

谢谢

【问题讨论】:

【参考方案1】:

使用所有这些嵌套的子上下文几乎肯定是错误的方法。在大多数情况下,您只需要在主线程上的一个主上下文,但是如果您有一大堆更改只有在完成并一起保存时才有意义,那么您可以为此使用临时子上下文。当您保存子上下文时,请立即保存主上下文以将其保存到磁盘上。把它想象成一个数据库事务。

如果您有来自后台进程的更改,您可以创建一个私有子上下文,或者直接从持久存储协调器创建一个完全独立的私有上下文 - 在第二种情况下,您必须手动将更改合并到主上下文中尽管。为此使用managedObjectContextDidSaveNotification:

【讨论】:

我理解你的建议,但为什么你认为这是一个错误的方法?如果我有一个嵌套的屏幕链,可以在第一个屏幕上取消,例如:我有 4 个上下文“层”,然后我在第 4 个上下文中进行一次更改,并保存它,然后在第 3 次更改保存它,但在第二个上下文中,用户决定取消整个事务。我认为父上下文链接是这样的 UX 的一个很好的解决方案,不是吗?这样,只有在每个步骤都得到确认的情况下,事情才会持续存在(这就是用户体验所需要的)。 developer.apple.com/reference/coredata/nsmanagedobjectcontext 父上下文而不是协调器。此模式有许多使用场景,包括: 在第二个线程或队列上执行后台操作。管理可丢弃的编辑,例如在检查器窗口或视图中。 我只是认为拥有多个这样的嵌套上下文听起来像是一种不必要的复杂方法。在任何情况下,使用managedObjectContextDidSaveNotification: 通知将交易中的更改合并到所有其他上下文中。每个孩子都需要注意其父母的保存并在那时提取更改。 也要从用户的角度来考虑。如果用户在上下文级别 4 和 3 保存后退出应用程序但没有直接回到顶部,他们是否会期望丢失所有数据?对我来说,“保存”意味着它被保存了,我不会失去它。

以上是关于使用父 NSManagedObjectContext 时正确的工作流程的主要内容,如果未能解决你的问题,请参考以下文章

在 macOS 中初始化 CoreData

如何在核心数据中以一对多关系链接现有值?

使用jquery获取父元素或父节点

当父组件使用 ng-content Angular 时从子组件访问父组件

winform子窗口与父窗口的交互-使用委托与事件

使用jquery获取父元素或父节点的方法