什么描述Objective-C和Cocoa Bindings最好?

时间:2009-02-27 15:20:40

标签: objective-c cocoa cocoa-bindings

我无法理解Cocoa Bindings。有人可以用人类可感知的方式向我解释这是什么吗?

2 个答案:

答案 0 :(得分:29)

Bindings是一个用于将视图连接到控制器的系统,无需编写大量粘合代码即可使它们明确地相互通信。您所要做的就是在两个类中设置属性*并在IB中连接绑定。

传统方法是视图有一个或多个与控制器通信的插座(最通用的示例是delegatetarget),控制器具有与视图通信的插座。当控制器更新模型时,它会发送(例如)[view modelChange:newModelObject]。当视图想要更新模型时,它会向其委托(控制器)发送一些委托消息,例如NSText的textDidChange:

使用Bindings,您在代码中所要做的就是在控件上的视图和属性上实现属性,然后将视图的一个或多个属性公开为绑定*。然后你只需要挂钩绑定。如果它是一个Cocoa类,那就是蛋糕:只需在IB中设置它。如果它是您自己的自定义类,您可能自己编写bind:toObject:withKeyPath:options:消息(并不难)。

让我重申一下:使用Bindings,您的整个胶水代码(大部分时间)在控制器中为[view bind:@"viewProperty" toObject:self withKeyPath:@"controllerProperty.modelProperty" options:options];。其他所有内容都由幕后的Bindings和KVO系统以及您的属性的访问者处理。

缺点是您必须严格遵守Cocoa Bindings的要求。这些很简单,但许多旧的应用程序的设计方式不适合Cocoa Bindings。

  • 您必须创建真实的模型对象,而不仅仅是传递原始对象(例如,字典数组)。如果您正在使用Core Data,这很容易:您的托管对象是模型对象。
  • 您必须正确编写访问者或合成正确的访问者。例如,NSString属性应始终为@property(copy),永远不应为@property(retain)(因为否则,您将发现自己保留了其他人的可变字符串,然后在您持有它时它们会发生变异)。
  • 您必须通过其属性(model.foo = bar)或访问者消息([model setFoo:bar])更改模型对象的属性,而不是通过直接实例变量访问。 (访问器方法本身的明显例外,如果你自己编写,因为它们必须直接访问实例变量。)

有两个好处:

  • 您可以编写全新的视图类,而无需删除大量的胶水代码。您必须删除的最多内容是旧视图属性的一些bind::::消息。如果,在未来的几年内,您认为您当前的视图无法扩展到您的应用程序即将推出的功能,这使您可以灵活地将其删除并以最小的痛苦重新开始。
  • 更重要的是,您需要阅读的代码越少,就越容易阅读。

*并且,根据文档,在视图类中实现KVO observation method,但我实际上从来没有必要这样做。我提交了a documentation bug

已添加2009-03-07:啊,发现了一个引文。 “NSView子类可以通过为每个属性调用类方法exposeBinding:来将其他键值编码/键值观察兼容属性公开为绑定。” - NSKeyValueBindingCreation所以你不需要实现一个KVO观察方法。

答案 1 :(得分:16)

以前的答案是非常全面和良好的,我只是想我会添加一个答案解释它的核心是什么而不涉及Cocoa或Objective-C。这是因为概念本身与语言无关,尽管像Objective-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 具有属性< strong> 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会自动处理这个问题。

摘要

Bindings允许您将两个属性绑定在两个不同的对象上,这样更改其中一个属性的值会导致另一个对象中的dependent属性更改为相同的值。