父/子托管对象上下文究竟是如何工作的?
Posted
技术标签:
【中文标题】父/子托管对象上下文究竟是如何工作的?【英文标题】:How do parent/child Managed Object Contexts exactly work? 【发布时间】:2015-09-12 15:22:59 【问题描述】:我的应用会定期向 Web 服务请求更新我使用 Core Data
持久化的对象。然后我需要更新我在主要上下文中拥有的对象(默认情况下在AppDelegate
中提供的对象)。编辑对象的不是用户,所以我需要避免阻塞 UI,此外我不只是修改对象信息,而是在需要时删除和添加新对象。
似乎有两个选项可以执行NSManagedObject
对象的更新:在私有队列中创建“兄弟”上下文,以及创建子上下文。阅读了几篇帖子,有更多人说最好使用父/子上下文(如果我错了,请纠正我),但我并不完全理解它是如何工作的。我有一些关于父/子上下文的问题:
-
子上下文可以在私有队列中,而父上下文可以在主队列中吗?
我在某处读过一些关于设置合并策略的内容,但我没有找到它的使用示例,也许在使用父/子上下文时不需要设置合并策略?什么时候设置?在哪里可以找到示例或教程?
如果我将私有上下文设置为主上下文的子上下文,并保存子私有上下文,那么私有上下文中的对象是否会按照我的意愿“替换”主上下文中的对象? (包括删除不再存在于私有上下文和新上下文中的对象)......我的意思是......整个子上下文是否替换了整个父上下文?
保存私有上下文而不是主上下文的子上下文,然后清除并重新获取主上下文中的所有新数据会更好吗?
在这个问题上我真的需要帮助,在此先感谢。
【问题讨论】:
【参考方案1】:是的,孩子可以在私有队列中,而父母可以在主队列中,相反的方式也有效。
合并策略...
您使用合并策略对象来解决托管对象的持久存储和内存版本之间的冲突。
因此,当您有多个直接来自persistentStoreCoordinator 的上下文时,您最常使用它,可能是一种私有队列类型和一种主队列类型。
合并策略影响调用结果
- (void)mergeChangesFromContextDidSaveNotification:(NSNotification *)notification
因此,如果您的删除操作是在专用队列中完成然后保存的,您可以通过在主上下文中调用 mergeChanges...
并使用来自
NSManagedObjectContextDidSaveNotification
Private 上下文中的保存将创建。
不会替换父上下文。简单地说,在子节点中所做的更改会覆盖在父节点上。因此,在您的情况下,删除子对象中的对象会导致该对象在您保存子对象后被删除。
没有。如果您不想使用父子上下文,最好执行 2 中描述的操作。您所描述的是丢弃您当前的主要上下文并创建一个新的上下文以反映 PSC 的新状态。它并不糟糕,但它很昂贵,如果您的 UI 与托管对象有任何紧密绑定,您需要确保这些对象也被重置。它更便宜只是合并保存。
使用 mergeChangesFromContextDidSaveNotification:
has been measured 比 parent->child 更快地进行更改传播,但您可能会发现 parent->child 在可读性方面更清晰。
【讨论】:
谢谢。我遇到的问题是,当我执行数据更新时,我从 Web 服务接收信息,我需要创建重复的对象以稍后检查它们的属性是否发生变化。我的意思是,如果我在主上下文中有一个objectA
,我调用一个服务,在私有上下文中创建另一个objectA
,然后对对象的两个版本进行一些比较。所以,我处理“相同”对象的两个版本,但理论上它们有不同的objectID
...
我在一个单独的线程中描述了这个场景:***.com/questions/32541859/…
你的后端对象有唯一ID吗?您应该将其存储在托管对象中以在两者之间进行关联以协调这一点。因此,在您的工人孩子中,您可以做query by UID and if(objectExistsLocallyAlready) delete object
是的,我设置了一种“主键”属性。那么,似乎在我的场景中合并更新的唯一方法是手动执行它们,对吗?因为从 Core Data 的角度来看,我没有管理相同的对象 ID...以上是关于父/子托管对象上下文究竟是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章
在 Core Data 中执行子获取时,在父上下文中修改托管对象是不是会向下传播到子上下文?