1

作为 Cocoa 和 Objective-C 的新手,我对 KVC 和 KVO 有一个初步的了解。然而,关于 Cocoa Bindings(如标题为“Cocoa Bindings Programming Topics”的 Apple 文档中所述,参见图 8-10),我不清楚他们为什么同时使用 KVC 和 KVO 来描述,而 KVO 似乎就足够了。KVO 的 ObserveValueForKeyPath:ofObject:change:context 可以提供新旧值,那么为什么需要 KVC 机制呢?请注意,我看到了 KVO 如何解耦对象,但 KVC 也是如此。

Apple 给出的示例(图 8-10)描绘了一个包含滑块和文本输入控件的窗口,以直观地表示并允许用户交互设置和查看“温度”、控制器对象和具有温度属性的模型对象。所以换一种说法,我的问题是为什么不只是在两个控件和控制器之间建立双向 KVO 关系(每个都作为观察者注册另一个),以及模型对象和控制器之间的双向 KVO 关系?为什么需要 KVC?

4

2 回答 2

2

冗长的文档让您感到困惑。

所有这些都是关于代码的可重用性。

(1) 提供一种标准的方式来声明和管理属性。(您可以使用 ivars 和 setter 和 getter 手动完成,但属性合成免费提供给您)

除非它们遵循约定,否则您无法可靠地观察键值对。约定是KVC。紧随其后的是 KVC 兼容。

(2) 为对象提供一种高度可重用和通用的方式来接收有关另一个对象中属性更改的通知。这是KVO。KVO 是基于首先符合 KVC 的属性的更改对通知进行通用编码的能力。

(3) 绑定和核心数据。这两种技术都建立在 KVC 和 KVO 之上,以使这一切都以尽可能通用的方式工作。

它在概念上也与 Active Record 和 Ruby on Rails 等 ORM 非常相似。魔法从 KVC 开始。KVC 启用了一个简单的 KVO 机制。KVO + KVC 使绑定和核心数据成为可能和容易。它们还提供了许多语法糖和古怪的便利。您可以将与 KVC 兼容对象的接口视为字典或数组。然后所有的模式都到位。

您仍然可以拥有其他双向观察者模式。委托(将彼此设置为或共享委托)和通知(通过 NSNotification),甚至只是简单地向其他对象发送消息(如果这是您的模式无处不在,则可能是糟糕的紧密耦合,导致创建这些其他模式)这些没有错,但有一些取舍。

通知有时可能是意大利面条代码。像所有回调一样,有时你会得到类似 goto 的东西。但是,它不一定与 KVO 等特定对象的特定属性紧密耦合。它只是在等待一个可能包含许多不同内容的可能非常笼统的通知。但是,就其性质而言,通知往往更针对用例,并且易于应用于自定义场景。

KVO as-a-specific-technology 建立在 KVC 约定之上,没有它们就无法工作。它使一些非常基本的、常见的样板代码和紧密耦合更容易创建。

于 2013-06-21T04:06:25.180 回答
1

一些人在评论中尝试过,他是我的选择:

KVO 本质上是建立在 KVC 之上的——当符合 KVC 的属性发生变化时,如果存在观察者,那么 KVO 机制就会启动,根据需要构建信息字典,并将消息发送给观察者。

如果他们的问题是为什么这样做,为什么不这样做,那么这是一个不同的问题。KVO 需要插入一些东西——你不能以简单的方式观察变量(内存位置)的变化[*]。具有 setter 和 getter 的属性是诸如 KVO 之类的东西可以挂钩的地方。属性遵循 KVC 模式,并且已经有机制支持它......但这并不意味着 KVO必须依赖于 KVC,其他实施策略无疑是可能的。

HTH 很少。

[*] 在这种情况下,进入调试模式并部署观察点并不“简单”!

于 2013-06-21T03:38:45.057 回答