14

我习惯于编写 Java Swing UI,如果您有一些更改的属性,并且您希望您的 UI 更新,您将实现观察者/可观察模式。在 Java 中,您通常通过让您的类维护它通知不同事件的侦听器列表来执行此操作。

我在 Mac 上玩过 Objective-C,它有 KVC 和绑定,看起来工作得很好,并且需要更少的代码。iPhone SDK 似乎没有此功能,所以我的问题是:如果我有一个包含更改数据的类,那么我向该类注册 UI 组件以便通知它的最佳方法是什么它需要显示的数据的变化?

4

3 回答 3

37

在 Cocoa 中有两种内置的观察方式:键值观察和通知。在这两个系统中,您都不需要自己维护或通知一组观察者;该框架将为您处理。

Key-Value Observing (KVO) 允许您观察对象的属性——甚至包括表示集合的属性——并在该属性发生更改时收到通知。您只需发送对象-addObserver:forKeyPath:options:context:,传递您想要接收更新的对象、您想要接收更新的属性的关键路径(相对于接收者)以及您想要接收的更新类型。(如果您想观察表示集合的属性,可以使用类似的方法。)

通知较旧且较重。您在一个NSNotificationCenter(通常是默认中心)注册一个对象和选择器对,以便在事件发生时传递通知。通知对象本身可以通过其userInfo属性包含任意数据,您可以选择观察特定名称的所有通知,而不是适用于特定对象的通知。

在任何特定情况下您应该使用哪个?一般来说,如果您关心对特定对象的特定属性的更改,请使用 Key-Value Observing。这就是它的设计目的,而且它是故意轻量级的。(在其他用途​​中,它是构建 Cocoa 绑定的基础。)如果您关心不是由属性表示的状态更改,那么通知更合适。

例如,为了在用户更改模型对象的名称时保持同步,我会使用 KVO。要知道何时保存了整个对象图,我会使用通知。

于 2008-10-03T09:16:51.380 回答
9

我还发现你可以这样做:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleWhateverChange) name:@"whateverChange" object:nil];

注册更改事件,以及

[[NSNotificationCenter defaultCenter] postNotificationName:@"whateverChange" object:nil];

解雇他们。我可能是 N00b,但我无法让关键路径的观察者为我工作。

于 2008-10-03T13:03:47.637 回答
0

这通常不是它的完成方式。看看这里的讨论,特别是 Apple 文档的链接。

如果您仍然想按照您所说的方式进行操作,那么“手动”实现诸如绑定之类的东西并不是特别难。您只需创建一个知道如何订阅更改并连接到视图属性的“绑定”对象。

要真正回答它是如何完成的 - 通常,您有一个控制器对象来监视模型的状态(充当类似于观察者的东西),并根据需要更新视图对象。

于 2008-10-03T06:04:50.793 回答