mergeChangesFromContextDidSaveNotification后的KVO通知 [英] KVO notifications after mergeChangesFromContextDidSaveNotification

查看:78
本文介绍了mergeChangesFromContextDidSaveNotification后的KVO通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using KVO to observe changes on a NSManagedObject. The NSManagedObject I'm observing is part of a NSManagedObject context that is on the main queue.

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

When I update this object in a background (private queue concurrency type) context and then merge the saved changes to my main queue context (in mergeChangesFromContextDidSaveNotification), KVO notifications fire as expected.

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

However, I expected that the notifications would only fire for key paths that actually changed and not for all keypaths of the NSManagedObject. I'm receiving KVO notifications for every keypath of my object even though they didn't change.

这是设计还是我做错了?

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

Can't see anything in the apple docs....

推荐答案

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

It is undocumented but observed behaviour on both OS X and iOS that a save counts as a change to the entire NSManagedObject not just differing elements. You can find grumblings about various consequences of that for bindings and the like around this site, on openradar.appspot.com, etc. That the problem also manifests with apparently-spurious KVO firings is completely unsurprising.

处理问题的最简单方法(好吧,最简单的方法是'只重新显示保存中的所有内容',我找到一个很好的第一次通过选项,直到有人抱怨)是监听通用保存通知,然后调用 - 在每个更新的对象上更改了值以选择您有兴趣为其发送特定更新的对象。

Simplest way to handle the problem (well, simplest after 'just redisplay everything on a save' which I find a fine first pass option until someone complains) is to listen for the generic save notification, then call -changedValues on each updated object to pick out the ones you're interested in firing specific updates for.

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

If that's hopelessly inefficient for your use case, you could make custom accessors (mogenerator is a big help with this) for your properties that collect on the editing thread flags for changes to all the properties you're interested in; and dispatch that as a notification after saving.

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

Let us for instance say that we have a professional sports team app that is updated constantly with JSON feeds parsed in the background. All display-affecting attributes of the various team, player, game, etc. NSManagedObjects have custom accessors that set flags in a structure of { playerStatsChanged, teamStatsChanged, leagueRankingsChanged, yadayadayadaChanged } corresponding to what pages in the app will need redisplay once the current fetch-and-parse thread completes. Then once it's saved, it fires off a generic 'update these screens' notification with that flag setting structure. You're probably coalescing individual change path notifications into some higher level 'update this screen' type logic somewhere in any case, right? Well, at the property setter level is pretty much the lowest overhead point you can do that at, for most reasonable use cases. Certainly for any recurring fetched update design such as our sports team apps here.

这篇关于mergeChangesFromContextDidSaveNotification后的KVO通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆