避免多个 NSManagedObjectContexts 之间的无限递归同步

Posted

技术标签:

【中文标题】避免多个 NSManagedObjectContexts 之间的无限递归同步【英文标题】:Avoiding infinite recursion synching between multiple NSManagedObjectContexts 【发布时间】:2010-07-28 22:01:06 【问题描述】:

设置:

我有两个托管上下文设置(在 iPhone 应用程序上)。我用于大多数查询的主要上下文和用于我希望在后台发生的长时间运行的操作的后台上下文。

我已经针对每个托管对象上下文设置了 NSManagedObjectContextDidSaveNotification 通知。为了响应通知,我调用 mergeChangesFromContextDidSaveNotification 进行同步。这也是一个要求,每当主上下文发生变化时,我需要在后台上下文中运行一些作业,因为现在事情的状态已经发生了变化。

只要只在其中一种上下文中写入,它就可以正常工作。在这种情况下,写在主要上下文上。但是,如果我在后台上下文中写入,则会导致无限循环。在后台上下文中保存会触发对主上下文的通知,主上下文依次合并更改并触发自己的通知,由后台上下文获取。这会触发后台上下文执行其后台作业,这些作业(如果他们写任何东西)再次开始循环。

这似乎是错误的设置,或者我需要一种方法来将“在主上下文发生更改时开始处理后台作业”与更改通知分离,或者我需要使后台上下文读取-仅限。

想法?与典型的“第二个上下文导入”场景不同,我相信我需要/希望我的背景上下文相对于主要上下文保持最新,以便我从我的背景中获得正确的结果工作。

【问题讨论】:

我不知道你的具体应用,但在一般的 CS 中,如果你有一个必须检测/打破的循环依赖,你可以添加状态(在包含两种情况下),因此您正在实施“标记和扫描”。 【参考方案1】:

听起来像是设计问题。虽然您可能可以绕过它,但您应该考虑避免使用“永久”背景上下文。我通常建议为每个操作建立一个上下文(NSOperations 非常适合),然后在一项工作完成时将它们丢弃。这避免了保持多个上下文同步的需要,因为您只需要更新主上下文。

为什么你认为你需要一个永久的背景上下文?如果是性能原因,你分析过吗?

【讨论】:

好点 - 我在我的脑海中认为创建一个新的上下文是多么“昂贵”,但不,我没有衡量它。我想很容易争辩说,如果背景上下文的原因是因为我需要做一些需要“很长时间”的事情,那么很容易证明在这段时间内分摊任何额外的启动开销是合理的。那么,根据您的经验,您的意思是创建一个新的上下文相对便宜? 创建一个新的上下文很昂贵,但它较少然后尝试保持两个上下文同步并保持后台线程运行(因为第二个上下文应该是 在该后台线程上创建,而不是传递给它)。所以,是的,创造是昂贵的,但远不如“以防万一”试图让一个人活着。【参考方案2】:

您可以为两个上下文创建一个NSSet,其中包含您收到的所有NSNotifications。每当您获得另一个时,只需在致电mergeChangesFromContextDidSaveNotification 之前检查一下。想想看,为任一上下文存储最后一个就足够了……

【讨论】:

以上是关于避免多个 NSManagedObjectContexts 之间的无限递归同步的主要内容,如果未能解决你的问题,请参考以下文章

避免多个包含 C++

如何避免多个精灵表?

BigQuery 避免多个子查询

如何避免 QNetworkAccessManager 多个 POST 请求?

避免 Sequelize 类的多个实例

如何避免命名管道中的多个作者?