【发布时间】:2009-02-27 15:20:39
【问题描述】:
我无法理解 Cocoa 绑定。有人能以人类可感知的方式向我解释这是怎么回事吗?
【问题讨论】:
-
“以人类可感知的(原文如此)方式”是什么意思?你在理解什么部分有困难?你的背景是什么?在提出问题时提前说明这些很重要。
-
魔术。具体来说,
NSMagic(未记录)
标签: objective-c cocoa cocoa-bindings
我无法理解 Cocoa 绑定。有人能以人类可感知的方式向我解释这是怎么回事吗?
【问题讨论】:
NSMagic(未记录)
标签: objective-c cocoa cocoa-bindings
Bindings 是一个用于将视图连接到控制器的系统,无需编写大量胶水代码来使它们显式地相互通信。您所要做的就是在两个类中设置属性*并在 IB 中连接绑定。
传统的方法是视图有一个或多个出口与控制器对话(最通用的例子是delegate 和target)并且控制器有出口与视图对话。当控制器更新模型时,它会发送(例如)[view modelChange:newModelObject]。当视图想要更新模型时,它会向它的委托(控制器)发送一些委托消息,例如 NSText 的textDidChange:。
使用绑定,您只需在代码中实现视图的属性和控制器的属性,然后将视图的一个或多个属性公开为绑定*。然后你只需要连接绑定。如果它是一个 Cocoa 类,这就是小菜一碟:只需在 IB 中设置它。如果它是您自己的自定义类,您可能会自己编写 bind:toObject:withKeyPath:options: 消息(难度不大)。
让我重申一下:使用 Bindings,您的整个粘合代码(大部分时间)在控制器中是 [view bind:@"viewProperty" toObject:self withKeyPath:@"controllerProperty.modelProperty" options:options];。其他一切都由幕后的 Bindings 和 KVO 系统以及您的属性的访问器处理。
缺点是您必须严格遵守 Cocoa Bindings 的要求。这些很简单,但许多旧应用程序的设计方式不适合 Cocoa Bindings。
@property(copy),而不应为@property(retain)(否则,您会发现自己保留了其他人的可变字符串,然后他们会在您持有它时发生变异)。model.foo = bar) 或访问器消息 ([model setFoo:bar]) 更改模型对象的属性,绝不能通过直接实例变量访问。 (如果您自己编写了访问器方法本身,则显然例外,因为它们必须直接访问实例变量。)有两个优点:
bind:::: 消息。如果在几年后,您认为当前视图无法扩展到应用程序即将推出的功能,那么您可以灵活地将其删除并以最小的痛苦重新开始。*并且,根据文档,在视图类中实现KVO observation method,但我实际上从未需要这样做。我提交了a documentation bug。
添加于 2009-03-07: 啊,找到了引用。 “NSView 子类可以通过调用类方法exposeBinding:为每个属性公开额外的键值编码/键值观察兼容属性作为绑定。” —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 会自动处理这个问题。
绑定允许您将存在于两个不同对象上的两个属性绑定在一起,以便更改其中一个属性的值会导致另一个对象中的依赖属性更改为相同的值。
【讨论】: