【问题标题】:What describes objective-C and Cocoa Bindings best?什么最能描述 Objective-C 和 Cocoa 绑定?
【发布时间】:2009-02-27 15:20:39
【问题描述】:

我无法理解 Cocoa 绑定。有人能以人类可感知的方式向我解释这是怎么回事吗?

【问题讨论】:

  • “以人类可感知的(原文如此)方式”是什么意思?你在理解什么部分有困难?你的背景是什么?在提出问题时提前说明这些很重要。
  • 魔术。具体来说,NSMagic(未记录)

标签: objective-c cocoa cocoa-bindings


【解决方案1】:

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

传统的方法是视图有一个或多个出口与控制器对话(最通用的例子是delegatetarget)并且控制器有出口与视图对话。当控制器更新模型时,它会发送(例如)[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。

  • 您必须创建真实的模型对象,而不仅仅是传递原始对象(例如字典数组)。如果您使用的是 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观察方法。

【讨论】:

  • 我认为彼得说得对。最大的优势是消除了所有更新用户界面其他部分的“胶水代码”。即使在一个中等大小的应用程序中,也可能有数千行您不需要编写的代码。
  • 我认为如果您正在处理作为集合的属性并且想要更新对 within项的更改,则必须在 NSView 子类中实现 KVO 观察协议> 收藏。
  • Barry Wark:不过,您不是必须注册为每个对象的观察者吗?当他们进来时添加你自己,当他们出去时移除你自己。这与绑定无关。
  • @Peter 要正确实现一对多绑定,几乎总是需要处理集合成员。不过,您是对的,情况并非总是如此。
  • 为什么你不应该写 bind:toObject:withKeyPath:options: 给自己发消息:tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings>.
【解决方案2】:

以前的答案非常全面和好,我只是想添加一个答案来解释它的核心是什么,而不特别涉及 Cocoa 或 Objective-C。这是因为这个概念本身与语言无关,尽管像 Objective-C 这样的动态语言比像 C++ 这样的静态语言更容易很多

示例

假设您有两个对象 MVM 有方法:

setX(int x);
setY(int y);
int getX();
int getY();

V 有方法:

setA(int x);
setB(int y);
int getA();
int getB();

看待这个问题的一种方式是 M 具有属性 xyV 具有属性 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 会自动处理这个问题。

总结

绑定允许您将存在于两个不同对象上的两个属性绑定在一起,以便更改其中一个属性的值会导致另一个对象中的依赖属性更改为相同的值。

【讨论】:

  • “所以我们希望在 M 上调用 setX 以在 V 上调用 setY。”应该读为:“所以我们希望在 M 上调用 setX 以导致在 V 上调用 setA。”还是很好的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 2011-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多