mergeChangesFromContextDidSaveNotification后的KVO通知

时间:2013-07-10 18:13:12

标签: ios objective-c xcode core-data key-value-observing

我正在使用KVO来观察NSManagedObject的变化。我正在观察的NSManagedObject是主队列中的NSManagedObject上下文的一部分。

当我在后台(专用队列并发类型)上下文中更新此对象,然后将保存的更改合并到我的主队列上下文(在mergeChangesFromContextDidSaveNotification中)时,KVO通知会按预期触发。

但是,我预计通知只会触发实际更改的密钥路径,并且 NSManagedObject的所有密钥路径。我正在接收对象的每个关键路径的KVO通知,即使它们没有改变。

这是设计还是我做错了?

在Apple docs中看不到任何内容......

2 个答案:

答案 0 :(得分:3)

它没有记录,但在OS X和iOS上观察到行为,保存计为整个NSManagedObject的更改,而不仅仅是不同的元素。你可以在openradar.appspot.com等网站上找到关于这个网站周围的绑定等各种后果的抱怨。这个问题也表现为明显虚假的KVO攻击并不令人惊讶。

处理问题的最简单方法(好吧,在'只重新显示保存上的所有内容之后最简单',我找到一个好的第一遍选项,直到有人抱怨)是监听通用保存通知,然后在每次更新时调用-changedValues反对挑选你有兴趣为其发射特定更新的那些。

如果这对你的用例来说是无效的,你可以为你的属性制作自定义访问器(mogenerator对此有很大帮助),这些属性收集编辑线程标志,以便更改你感兴趣的所有属性;并在保存后作为通知发送。

让我们举个例子说我们a professional sports team app不断更新,并在后台解析JSON提要。各种团队,玩家,游戏等所有影响显示属性的属性.NSManagedObjects具有自定义访问器,在{playerStatsChanged,teamStatsChanged,leagueRankingsChanged,yadayadayadaChanged}的结构中设置标志,对应于应用程序中的哪些页面需要重新显示一次当前获取并解析线程完成。然后,一旦它被保存,它将通过该标志设置结构触发通用的“更新这些屏幕”通知。在任何情况下,您可能会将单个更改路径通知合并到某个更高级别的“更新此屏幕”类型逻辑中,对吧?好吧,对于大多数合理的用例,属性setter级别几乎是你可以做到的最低开销点。当然,对于任何重复提取的更新设计,例如我们的运动团队应用程序。

答案 1 :(得分:0)

您可以使用手动通知覆盖自动更改通知,仅针对您选择的键。查看详细文档here