【问题标题】:What's the nicest way to do observer/observable in objective-c (iphone version)在objective-c(iphone版)中做观察者/可观察的最好方法是什么
【发布时间】:2010-09-15 00:18:57
【问题描述】:

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

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

【问题讨论】:

    标签: iphone objective-c cocoa


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 很好的答案 - 但是使用 KVO 方法,您如何删除注册了许多对象的观察者?我(错误地)认为 KVO 在后台使用了通知 - 但我不认为它确实如此。因此,在使用 addObserver:X forKeyPath:... 之后,如果您稍后尝试这样做: [[NSNotificationCenter defaultCenter] removeObserver: X] 这不起作用?这似乎意味着您必须保留 X 正在观察的所有对象的单独列表,以便您可以删除观察结果。还是我错过了什么?
    • @TimM:您将为观察到的对象调用适当的方法。例如:[self removeObserver:theObserver forKeyPath:@"someProperty"];
    • OS X 10.7 Lion 和 iOS 5.0 中的新功能,有一个方法 -removeObserver:forKeyPath:context: 您可以将添加观察者时传递的相同上下文传递给该方法。您应该尽可能地这样做,以防多个对象观察相同的键路径。
    【解决方案2】:

    我还发现你可以这样做:

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

    注册更改事件,并且

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 我只是在问什么方法最好,并给出一个 JAVA 示例。如果 Objective-C 的方式完全不同,我并不特别在意,我只是想知道它是什么。
      • 知道了。我编辑了我的答案,以便更清楚地说明我在说什么。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 2011-06-17
      • 2014-03-24
      • 1970-01-01
      相关资源
      最近更新 更多