是否允许对performBlockAndWait:的递归调用?

时间:2015-06-18 22:16:09

标签: ios core-data

上下文:使用核心数据,我在私有队列(我将调用mainContext)上有一个主上下文,在主队列上有另一个上下文,main的子节点(我将调用{{1 }})。队列无关紧要,我的问题的答案不应该依赖于上下文所在的队列。

我的目标是直接保存childContext对磁盘的修改,而不会让childContextmainContext带来的修改保存到磁盘之前进行任何修改。

为了做到这一点,我打电话给:

childContext

背后的想法是,如果我执行一个块并同时等待子和父上下文,则在保存子项时不能对主上下文进行任何修改。然后保存主上下文,我们退出块。该文件明确指出,对[self.childContext performBlockAndWait:^{ [self.parentContext performBlockAndWait:^{ [self.childContext save:NULL]; [self.parentContext save:NULL]; }]; }]; 的调用是可重入的,因此这应该有效。

是吗?对performBlockAndSave:的嵌套调用是否有效?显然,保存在performBlockAndWait:的队列中完成,并且mainContext的队列在保存期间未被锁定。这是正常的吗?如果是这样,我怎样才能实现目标?

注意:由于我与API通信的方式,我需要这种原子性。要在我的API上创建一个对象,我在本地创建对象,然后检查Core Data上下文中的本地修改,并将这些修改转换为API调用。如果我打电话:

childContext

[self.childContext performBlockAndWait:^{ [self.childContext save:NULL]; /* 1 */ [self.parentContext performBlockAndWait:^{ [self.parentContext save:NULL]; }]; }]; performBlock:可能会在mainContext保存performBlockAndWait:mainContext)之前调用1。这个电话会有一个不洁净的"上下文,来自childContext的更改等待保存在磁盘上。

1 个答案:

答案 0 :(得分:1)

我认为解决方案是在上下文层次结构中进一步创建更多子上下文。

请允许我为了清晰起见重新命名您的上下文:

我们拨打mainContext rootContext (后台,保存到持久商店)。
让我们调用childContext mainContext (主线程上下文,rootContext的子项)。
让我们将任何较低的子上下文称为“工作者上下文”(背景,mainContext的孩子)。

工作者上下文应该是主要上下文作为父项的背景上下文。

您可以将根上下文保存到物理存储的中心位置,例如您管理核心数据堆栈的位置。

据我了解,当通过save:将更改从工作区上下文推送到主上下文时,同时主上下文本身会在performBlockAndWait中将更改推送到其父上下文阻止,它只会在完成后获得更改。只有这样,它才能将它们进一步推送到根上下文以进行物理保存。我认为这应该实现你的原子性目标。

通过引入工作者上下文,您确保根上下文不会从除主要上下文之外的任何其他地方接收任何更新。