我习惯于编写Java Swing UI,如果你有一些属性发生变化,并且你希望你的UI更新,你将实现观察者/可观察模式。在Java中,您通常通过让您的类维护一个监听器列表来通知不同的事件来完成此任务。
我在Mac上玩过Objective-C,它有KVC和绑定,看起来非常好用,并且需要的代码更少。 iPhone SDK似乎没有这个功能,所以我的问题是: 如果我有一个包含更改数据的类,那么我最好的方法是向该类注册一个UI组件,以便可以通知它需要显示的数据变化?
答案 0 :(得分:37)
在Cocoa中有两种内置的观察方式:键值观察和通知。在这两个系统中,您都需要自己维护或通知一组观察者;框架将为您处理。
键值观察(KVO)允许您观察对象的属性 - 甚至包括表示集合的属性 - 并被告知该属性的更改。您只需要发送对象-addObserver:forKeyPath:options:context:
,传递要接收更新的对象,要为其接收更新的属性(相对于接收方)的关键路径,以及要接收的更新类型。 (如果要观察表示集合的属性,可以使用类似的方法。)
通知较旧且较重。您注册NSNotificationCenter
- 通常是默认中心 - 在事件发生时传递通知的对象和选择器对。通知对象本身可以通过其userInfo
属性包含任意数据,您可以选择观察特定名称的所有通知,而不是适用于特定对象的通知。
在任何特定情况下,您应该使用哪种?通常,如果您关心对特定对象的特定属性的更改,请使用键值观察。这就是它的设计目标,它有意轻巧。 (在其他用途中,它是构建Cocoa Bindings的基础。)如果您关心的是状态的更改,而不是由属性表示,则通知更合适。
例如,要在用户更改模型对象的名称时保持同步,我将使用KVO。要知道保存整个对象图的时间,我会使用通知。
答案 1 :(得分:9)
我还发现你可以这样做:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_handleWhateverChange) name:@"whateverChange" object:nil];
注册变更事件,
[[NSNotificationCenter defaultCenter] postNotificationName:@"whateverChange" object:nil];
解雇他们。我可能是一个N00b,但我无法让关键路径的观察者为我工作。
答案 2 :(得分:0)
这通常不是它完成的方式。请查看讨论here,特别是Apple文档的链接。
如果你仍然想按照你说的方式去做,那么实现像“手工”绑定这样的东西并不是特别困难。您只需创建一个“绑定”对象,该对象知道如何订阅更改,并连接到视图的属性。
要真正回答它是如何完成的 - 通常,你有一个控制器对象来监视模型的状态(像Observer一样),并根据需要更新视图对象。