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