上下文:使用Core Data,我在专用队列上有一个主上下文(我将称为mainContext
),在主队列上还有一个上下文,即主队列的子级(我将称为childContext
)。队列无关紧要,我的问题的答案不应取决于上下文所在的队列。
我的目标是将childContext
的修改直接保存到磁盘上,而在mainContext
带来的修改保存到磁盘之前,不要让childContext
进行任何修改。
为此,我致电:
[self.childContext performBlockAndWait:^{
[self.parentContext performBlockAndWait:^{
[self.childContext save:NULL];
[self.parentContext save:NULL];
}];
}];
其背后的想法是,如果我同时执行一个块并在子级和父级上下文上等待,则在保存子级时不能对主上下文进行任何修改。然后保存主上下文,然后退出块。该文档明确指出,对
performBlockAndSave:
的调用是可重入的,因此应该可以使用。可以?对
performBlockAndWait:
的嵌套调用是否有效?显然,保存是在mainContext
队列上完成的,并且childContext
队列在保存期间未锁定。正常吗如果是这样,我如何实现我的目标?注意:由于我与API通信的方式,我需要这种原子性。要在我的API上创建对象,我先在本地创建对象,然后检查Core Data上下文中的本地修改,然后将这些修改转换为API调用。如果我打电话给:
[self.childContext performBlockAndWait:^{
[self.childContext save:NULL];
/* 1 */
[self.parentContext performBlockAndWait:^{
[self.parentContext save:NULL];
}];
}];
在
performBlock:
保存mainContext
之前(在performBlockAndWait:
处),有可能在mainContext
上调用1
。该调用将具有“不干净”的上下文,childContext
中的更改将等待保存到磁盘上。 最佳答案
我认为解决方案是在上下文层次结构中进一步创建更多子上下文。
为了清楚起见,请允许我重命名您的上下文:
让我们将mainContext
称为rootContext
(背景,保存到持久性存储中)。
让我们将childContext
称为mainContext
(主线程上下文,rootContext
的子代)。
让我们将任何较低的子级上下文称为“工作人员上下文”(背景,mainContext
的子级)。
工作程序上下文应为以主要上下文为父级的背景上下文。
您可以在中心位置放置根上下文将其保存到物理存储,例如您可以在其中管理核心数据堆栈。
据我了解,当通过save:
将更改从工作人员上下文推送到主上下文时,同时主上下文本身在performBlockAndWait
块中将更改推送到其父上下文,它将仅获得完成后更改。只有这样,它才能将它们进一步推向要物理保存的根上下文。我认为这应该可以实现您的原子性目标。
通过引入辅助上下文,您可以确保根上下文不会从主上下文接收任何其他更新。