iphone - 在 Objective-C 中绑定(bind)模型类的方法

标签 iphone objective-c model-view-controller key-value-observing nsnotifications

(如果我弄错了,我希望有人能纠正我的术语——我仍在整理术语)

我的模型中有一系列类。我需要从 url (SatDataGetter) 获取一些数据,并将其与特定于位置和日期的计算 (DayCalculator) 结合起来,进行一些进一步的计算 (DataMixer),进行一些解释以使其易于用户理解 (Advisor),然后呈现结果在 View 中。

例如,设置依赖项并确保 SatDataGetter 具有有效数据时存在问题 之前 它被 DataMixer 调用,之前 它被称为..你明白了。当然,如果位置发生变化,我需要自下而上更新整个事情。至少我必须向 ViewController 和 Advisor 发送消息以重新加载它们的数据。

我所做的研究表明 NSNotification 是一种方法,但我也可以尝试键值观察。我在 KVO 上发现了一些旧帖子(2009 年),其中提出了一些可能存在的问题和调试困难。 http://www.mikeash.com/pyblog/key-value-observing-done-right.html

什么是首选方法?我在决定时应该考虑哪些问题——
例如:
SatDataGetter 本质上返回一个数字。 KVO 似乎是 DataMixer 跟踪该值的合理方法,但我不认为我希望所有父类都对因变量执行 KVO。

你什么时候选择 NSNotification,什么时候选择 KVO?

最佳答案

NSNotifications 和 Key-Value Observation 之间的区别主要是耦合之一,但也有性能影响。

任何人都可以订阅您的 NSNotifications。他们只需要知道您在其下通知的字符串/键。他们不需要知道关于你的类/对象图等的任何信息。所以当你想通知一个不知道你的类的细节的世界时, NSNotification 是要走的路。例如,如果您要向其他开发人员出售一个框架,那么通过 NSNotification 进行通知可能比将您的框架内部公开到允许消费者对您的对象进行键值观察所必需的程度更好。

为了 KVO 观察一个对象,您首先必须能够获得对它的引用,这对于 NSNotifications 来说并非严格正确(但在我的经验中通常是正确的。)其次,您需要对实现有足够的了解才能知道要观察什么。使用 NSNotification 通知程序只需要发布一个通知字符串/ key 。使用 KVO,您需要知道对象的属性名称。当然,有人可以发布静态字符串并告诉你“你可以为这些属性 KVO 我”,但这实际上变成了一个 API 契约,可能更难维护。 (比如说,你想在 future 的版本中删除那个属性——然后你必须设置其他东西来继续发送这些通知并在人们调用 valueForKey 时提供值:——简而言之,一旦你这样做了,您永远无法更改该属性。)

对于这些不同程度的耦合要记住的另一件事是,对于 KVO,可能期望观察者知道您的类/对象的详细信息。毕竟,他们对您的对象表现出非常特殊的兴趣;他们声称知道这意味着什么——它是如何运作的。因此,您可能期望它们对性能影响很敏感。使用 NSNotifications,消费者可以观察您的通知,几乎对您一无所知,并且可能不会意识到他们如何响应通知的性能影响。

这两种方法共有的缺点是,如果没有额外的工作,它们都是同步交付的。通知对象受观察者在接收通知时选择(同步)执行的操作的支配。这两种机制的不同之处在于,对于 NSNotification,通知对象很容易使用 performSelector:afterDelay: 使通知在下一次运行时“异步”发送(相对于产生通知的调用)循环(另见 NSNotificationQueue)。这对于 KVO 来说不是那么容易实现的。在某些情况下,仅这种差异就可能是至关重要的。

通常,我发现 NSNotification 的松散耦合适用于大粒度(即可能代表一大群更改)或相对不频繁的事件。 KVO 通知本质上是细粒度的。您正在明确观察单个对象上单个属性(每个注册)的更改。这有可能使注册数量和通知数量激增。每个观察都有性能成本。

这两者的另一个共同缺点是可调试性。我在上面的评论中提到 KVO 对调试来说可能是一个挑战,它也与 NSNotificationCenter 共享这一挑战。

这两者与委托(delegate)模式之间的主要区别在于委托(delegate)关系通常是 1:1(一个委托(delegate))。(当然,您可以拥有一组委托(delegate),但这种情况非常罕见,并且可能是一种反模式。) NSNotification 和KVO 本质上都是 1:N(许多观察者)。

最后,我总是喜欢说,“使用能够完成工作的最高抽象级别。”如果您只需要 1:1 的关系,请使用委托(delegate)。对于 1:N 通知,如果 NSNotification 可以工作——换句话说,如果所需的耦合较低和/或通知是大粒度的或不频繁的,请使用 NSNotifications。如果耦合紧密,或者需要细粒度,请使用 KVO。还请记住,您可以通过让委托(delegate)发送 NSNotifiations 来调整从 1:1 到 1:N 的委托(delegate)模式。使用 NSNotifications 和 KVO,您无法真正控制谁观察您或您拥有多少观察者。

关于iphone - 在 Objective-C 中绑定(bind)模型类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7595389/

相关文章:

iphone - 如何在我的 iPhone/iPad 的状态栏中显示播放图标

objective-c - 将 NSDecimalNumber 显示为 IB 中的货币

ios - 为 Storyboard VC 初始化程序化 VC

c# - View 创建部分(子) View 是不好的做法吗?

html - 网站在 iPhone 上旋转 180 度

iphone - 在 ViewController 中设置自定义 UITableViewCell 的 UILabel.text

asp.net-mvc - 更改 OnActionExecuting 事件中的模型

c++ - QTreeView 不显示标题

iphone - 将鼠标悬停在 iPhone 上 UIButton 的状态上

iphone - 刷新 UITableView