【发布时间】:2011-09-20 01:15:24
【问题描述】:
我想知道在 KVO 与 NSNotificationCenter 观察中是否有理由使用其中一个。性能、内存使用、速度等?
【问题讨论】:
标签: cocoa binding key-value-observing nsnotificationcenter nsnotification
我想知道在 KVO 与 NSNotificationCenter 观察中是否有理由使用其中一个。性能、内存使用、速度等?
【问题讨论】:
标签: cocoa binding key-value-observing nsnotificationcenter nsnotification
这两者并不总是可以互换的。从概念上讲,KVO 仅用于观察对象的 property。例如,您不能使用 KVO 替换 NSApplicationWillTerminateNotification,因为它会通知观察者发生的事件,而不是对象属性的更改。
就性能和内存使用而言,它们都很快并且使用的内存可以忽略不计。 NSNotificationQueue 已合并以阻止通知泛滥。据我所知,KVO 没有任何合并,这确实在某一时刻给我带来了性能问题。我观察了数百个对象,当这些对象发生批量更新时,我会收到数百个 KVO 回调。这不是 KVO 本身的性能问题,而是由于批量更新而运行的我自己的代码。
性能并不是真正的问题,更重要的是最适合该问题。如果是属性更改,请使用 KVO。如果不是属性更改,请使用委托或通知,具体取决于您需要单个观察者还是多个观察者。
【讨论】:
一个很老的问题,但想加点。我同意Tom Dalling's answer,但是,在大型应用程序中有许多场景,我们倾向于为对象的属性添加观察者,但我们不能,或者我们错过了从观察者列表中删除它们的机会。
让我们从我的应用程序中考虑以下场景 - 一个 ViewController 显示一个蛇对象,我正在观察这个对象的属性变化 - “毒液”。因此,每当 viewController 需要显示不同的蛇时,我只需从该蛇对象的观察者中删除视图控制器。
应用程序演变为显示蛇列表而不是单个蛇,这意味着我必须观察该对象中所有蛇的属性。现在,当从数组中删除一条旧蛇时,我应该了解这个事件,以便我可以从这个蛇对象中删除作为观察者的视图控制器。为此,我必须首先观察数组本身的变化。为此,我必须遵循特定的协议将对象插入数组并将它们从数组中删除。这样,复杂性就建立起来了。我们都知道不从对象中删除观察者的后果以及该对象是否被操作系统释放!
以上只是一个例子,这里的主要问题是 我无法获取给定对象的 KVO 观察者列表,以便在该对象被释放之前将其从观察者中删除 - 这很容易由 NSNotification 和 NSNotificationCenter 实现。有时,我倾向于使用 NSNotification 而不是 KVO,但是,在良好的设计实践方面,KVO 总是优于通知。
【讨论】: