10

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

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

但是,我预计通知只会针对实际更改的关键路径而不是NSManagedObject 的所有关键路径触发。我收到了我的对象的每个键路径的 KVO 通知,即使它们没有改变。

这是设计使然还是我做错了什么?

在苹果文档中看不到任何内容....

4

2 回答 2

3

在 OS X 和 iOS 上,保存被视为对整个 NSManagedObject 的更改,而不仅仅是不同的元素,这是未记录但观察到的行为。您可以在本网站、openradar.appspot.com 等网站上找到有关绑定等各种后果的抱怨。这个问题也体现在明显虚假的 KVO 触发上,这完全不足为奇。

处理问题的最简单方法(嗯,最简单的“只是在保存时重新显示所有内容”之后,我找到了一个很好的第一次通过选项,直到有人抱怨)是监听通用保存通知,然后在每个更新的对象上调用 -changedValues 来选择找出您有兴趣为其触发特定更新的那些。

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

例如,假设我们有一个专业的运动队应用程序使用在后台解析的 JSON 提要不断更新。各种球队、球员、比赛等的所有影响显示的属性。 NSManagedObjects 具有自定义访问器,它们在 { playerStatsChanged, teamStatsChanged, LeagueRankingsChanged, yadayadayadaChanged } 结构中设置标志,对应于应用程序中的哪些页面需要在当前获取后重新显示-and-parse 线程完成。然后,一旦保存,它就会使用该标志设置结构触发通用的“更新这些屏幕”通知。在任何情况下,您都可能将单个更改路径通知合并到某个更高级别的“更新此屏幕”类型逻辑中,对吧?好吧,对于大多数合理的用例,在属性设置器级别几乎是您可以做到的最低开销点。

于 2013-07-10T22:22:32.930 回答
0

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

于 2013-07-10T18:27:12.477 回答