避免多个 NSManagedObjectContext 之间的无限递归同步
设置:
我有两个托管上下文设置(在 iPhone 应用程序上)。我用于大多数查询的主上下文和我希望在后台发生的长时间运行操作的后台上下文。
我已经针对每个托管对象上下文设置了 NSManagedObjectContextDidSaveNotification 通知。为了响应通知,我调用 mergeChangesFromContextDidSaveNotification 进行同步。还有一个要求是,每当主上下文发生变化时,我都需要在后台上下文上运行一些作业,因为事物的状态现在已经发生了变化。
只要只在其中一个上下文中写入,这就可以正常工作。在这种情况下,请根据主要上下文进行写作。但是,如果我在后台上下文上写入,这会导致无限循环。保存在后台上下文上会触发对主上下文的通知,而主上下文又会合并更改并触发其自己的通知,由后台上下文拾取。这会触发后台上下文执行其后台作业,这(如果它们写入任何内容)再次开始循环。
看来这要么是错误的设置,要么我需要一种方法来将“主上下文发生变化时开始处理后台作业”与更改通知分离,或者我需要将后台上下文设置为只读。
有想法吗?与典型的“第二上下文用于导入”场景不同,我相信我需要/希望我的背景上下文相对于主上下文保持最新,以便我从背景中获得正确的结果工作。
The setup:
I have two managed contexts setup (on an iPhone application). A main context that I use for most queries and a background context I use for long running operations that I want to happen in the background.
I've setup notifications for NSManagedObjectContextDidSaveNotification against each managed object context. In response to the notification, I call mergeChangesFromContextDidSaveNotification to sync up. It is also a requirement that any time things change on the main context, I need to run some jobs on the background context, as the state of things has now changed.
This works fine, as long as only write in the one of the contexts. In this case, writing on the main context. However, if I write on the background context, this causes an infinite loop. Saving on the background context triggers the notification to the main context, which in turn merges the changes and fires its own notification, picked up by background context. This triggers the background context to perform its background jobs, which (if they write anything) start the cycle again.
It seems that either this is the wrong setup, or I need a way to decouple the "start processing background jobs any time something changes on the main context" from the change notification, or I need to make the background context read-only.
Ideas? Unlike a typical "second-context-is-for-importing" scenario, I believe that I need/want my background context to remain up-to-date with respect to the main context, so that I get the proper results from my background job.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
听起来像是一个设计问题。虽然您可能可以绕过它,但您应该考虑避免使用“永久”背景上下文。我通常建议为每个操作建立一个上下文(NSOperations 非常适合),然后在一项工作完成后将其丢弃。这避免了保持多个上下文同步的需要,因为您只需要更新主上下文。
您认为为什么需要永久的背景环境?如果是性能原因你分析过吗?
Sounds like a design issue. While you can probably get around it, you should consider avoiding having a "permanent" background context. I normally recommend standing up a context per operation (for which NSOperations work great for) and then throw them away when that one job is complete. This avoids the need to keep multiple contexts in sync as you only need to update the main context.
Why do you think you need a permanent background context? If the reason is performance have you analyzed it?
您可以为两个上下文创建一个
NSSet
,其中包含您收到的所有NSNotifications
。每当您获得另一个通知时,只需在调用mergeChangesFromContextDidSaveNotification
之前将其与其他通知进行检查即可。想想看,存储任一上下文的最后一个应该就足够了……You could create an
NSSet
for both contexts which contain allNSNotifications
you have received. Whenever you get another one, just check it against those before callingmergeChangesFromContextDidSaveNotification
. Come to think of it, storing the last one for either context should be enough…