我很难理解 Cocoa Bindings。有人能以人类可感知的方式向我解释这一切是什么吗?
2 回答
Bindings 是一个系统,用于将您的视图连接到您的控制器,而无需编写大量胶水代码来使它们显式地相互通信。您所要做的就是在两个类* 中设置属性并在 IB 中连接绑定。
传统的方法是视图有一个或多个出口与控制器对话(最通用的例子是delegate
and target
),而控制器有出口与视图对话。当控制器更新模型时,它会发送(例如)[view modelChange:newModelObject]
. 当视图想要更新模型时,它会向其委托(控制器)发送一些委托消息,例如 NSText 的textDidChange:
.
使用绑定,您在代码中所要做的就是在视图上实现属性并在控制器上实现属性,然后将视图的一个或多个属性公开为绑定*。然后你只需要连接绑定。如果它是一个 Cocoa 类,这就是小菜一碟:只需在 IB 中设置它。如果它是您自己的自定义类,您可能会bind:toObject:withKeyPath:options:
自己编写消息(难度不大)。
让我重申一下:使用 Bindings,您的整个胶水代码(大部分时间)都[view bind:@"viewProperty" toObject:self withKeyPath:@"controllerProperty.modelProperty" options:options];
在控制器中。其他一切都由幕后的绑定和 KVO 系统以及您的属性的访问器处理。
缺点是您必须严格遵守 Cocoa Bindings 的要求。这些很简单,但是许多旧应用程序的设计方式不适合 Cocoa Bindings。
- 您必须创建真实的模型对象,而不仅仅是传递原始对象(例如字典数组)。如果您使用 Core Data,这很容易:您的托管对象是模型对象。
- 您必须正确编写访问器或合成正确的访问器。例如,一个 NSString 属性应该永远是
@property(copy)
, never@property(retain)
(因为否则,你会发现自己保留了别人的可变字符串,然后他们会在你持有它时改变它)。 - 您只能
model.foo = bar
通过它们的属性 ( ) 或访问器消息 ( )更改模型对象的属性[model setFoo:bar]
,绝不能通过直接实例变量访问。(访问器方法本身的明显例外,如果您已经编写了自己的,因为它们必须直接访问实例变量。)
有两个优点:
- 您可以编写一个全新的视图类,而无需撕掉大量的胶水代码。您最多需要删除的是
bind::::
旧视图属性的一些消息。如果在几年后,您认为您当前的视图无法扩展到您的应用程序即将推出的功能,那么您可以灵活地将其删除并以最小的痛苦重新开始。 - 更重要的是,你必须阅读的代码越少,阅读起来就越容易。
*并且,根据文档,在视图类中实现KVO 观察方法,但我实际上从来没有这样做过。我提交了一个文档错误。
添加于 2009-03-07:啊,找到了引用。“NSView 子类可以通过调用类方法exposeBinding:为每个属性公开额外的键值编码/键值观察兼容属性作为绑定。” —<a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSKeyValueBindingCreation_Protocol/Reference/Reference.html" rel="noreferrer">NSKeyValueBindingCreation 所以你不需要实现一个KVO 观察法。
以前的答案非常全面和好,我只是想添加一个答案来解释它的核心是什么,而不具体涉及 Cocoa 或 Objective-C。这是因为这个概念本身与语言无关,尽管像 Objective-C 这样的动态语言比像 C++ 这样的静态语言要容易得多。
例子
假设您有两个对象M和V。M有方法:
setX(int x);
setY(int y);
int getX();
int getY();
虽然V有方法:
setA(int x);
setB(int y);
int getA();
int getB();
看待这一点的一种方式是M具有属性x和y并且V具有属性a和b。您希望属性x的更改导致属性b的更改和y的更改导致 a 的更改。
通过属性x的变化,我们的意思是例如:
M.setX(10)
以前在哪里
M.getX() != 10
因此,我们希望在M上调用setX以在V上调用setA。
绑定允许您说的是对象V上的属性b绑定到对象M上的属性x。然后自动处理此更新。作为编码人员,您不必编写代码来检查x是否已更改,然后在V上调用setB。Bindings 会自动处理这个问题。
概括
绑定允许您将存在于两个不同对象上的两个属性绑定在一起,以便更改其中一个属性的值会导致另一个对象中的从属属性更改为相同的值。