核心数据

时间:2017-11-17 12:20:01

标签: ios cocoa core-data

我对Core Data Programming Guide的理解是,在保存上下文时,对于该上下文的每个托管对象,Core Data框架会比较上次提取对象时所采用的值的快照与当前对应的对象的快照。持久性存储中的值。使用默认NSErrorMergePolicy,如果与这些快照关联的版本号不同,则尝试保存上下文将引发错误。

但是,我观察到,鉴于已经进行更改的后台上下文,即使在此期间另一个上下文(主UI上下文)也对其中一个托管对象进行了更改,上下文也会产生保存冲突但尚未调用将这些更改保存到持久性存储

我的问题是:虽然我认识到同时写入两个上下文的显而易​​见性 - 当这个上下文首先保存时,后台上下文如何能够触发保存冲突?主要上下文仅写入其中一个托管对象 - 最多可能调用processPendingChanges - 但没有保存。

其他细节

我应该注意上面示例中的两个上下文共享相同的持久性存储协调器。我想知道在这个级别是否有一些沟通我不考虑。但是,我认为关键是上下文是“孤立的暂存区”,它们独立行动,直到调用保存提交/将更改合并到商店作为事务。我也认识到我可以通过改变合并策略来解决问题,但是缺乏与我有关的隔离。我也在两个上下文中观察对象更改和上下文保存通知,所以我不认为有一个我不知道的虚假保存。但是我还错过了什么?

最后,由于问题本质上与结构/时序相关,因此很难显示代码。但是,任何其他建议,以准确发现UI上下文何时触及PSC /商店以增加版本编号 - 将非常感激。

1 个答案:

答案 0 :(得分:2)

我发现了问题,如果其他人观察到相似的行为,这可能是一个有用的问题。

我相信我在问题中的假设确实是正确的,并且在第一次传递时,一切都按预期运行可能并不是很明显。但是,在稍后的传递中,在我的情况下,主UI可能已经调用以保存其上下文,而后台上下文中的托管对象自第一次(成功)保存调用以来保持相同的状态。这是第二次调用以保存引发保存冲突的背景上下文。

确认此类问题的直接解决方案是在启动附近的某个地方调用refreshAllObjects()refresh(_:mergeChanges:)可能具有陈旧对象的处理块。这将确保上下文中的托管对象使用持久性存储中的最新更改进行更新,因此在此块期间不会发生任何保存,以后稍后调用save应该看不到冲突。

我应该提一下,我不想说这是解决这个问题的好方法 - 我只是想了解发生了什么。