为什么我要使用NSObjectController?

14

虽然我已经搜索了很多有关Cocoa Bindings的信息,但我对自己得到的信息仍然感到相对不满意。看起来这个主题对很多人来说都有些棘手,很多人只是避免使用这种模式,我认为这种情况不应该发生。

当然,绑定有时可能过于复杂或设计过于繁琐...

然而,我有一个非常直接和具体的问题:如果我可以直接建立绑定,为什么还需要NSObjectController呢?

例如,下面的代码:

[controller bind:@"contentObject" toObject:self withKeyPath:@"numberOfPieSlices" options:nil];

[slicesTextField bind:@"value" toObject:controller withKeyPath:@"content" options:nil];
[stepperControl bind:@"value" toObject:controller withKeyPath:@"content" options:nil];

与其完全相同的功能:

[slicesTextField bind:@"value" toObject:self withKeyPath:@"numberOfPieSlices" options:nil];
    [stepperControl bind:@"value" toObject:self withKeyPath:@"numberOfPieSlices" options:nil];

在我的情况中,我们谈论的是正在发生一切的类的属性,因此我猜想需要 NSObjectController 的原因可能是:

  • 当控制器的键路径为 object 且需要将其他控件的绑定与其属性进行绑定,而不是像使用基本类型和其包装器一样绑定其值(在我的情况下,numberOfPiesSlices 是 NSInteger)时

  • 或者当需要在一个对象内部之间以及外部其他对象之间进行绑定时

有人能够确认或者反驳吗?

2个回答

12

绑定的好处之一是可以消除代码。为此,NSObjectController等具有可以直接在界面构建器中使用并设置为绑定到各种UI元素的优点。

绑定仅代表提供的功能的一部分。*ObjectController类还可以自动处理应用程序通常需要的其他更多重复控制器(作为模型、视图和控制器)代码。例如,它们可以:

  • 连接到核心数据存储,并执行必要的获取、插入和删除操作
  • 管理撤销/恢复堆栈
  • 捕获已编辑但未提交的UI更改并保存它们(例如,如果在焦点仍在编辑的文本字段上而关闭窗口,则这是一个新颖的发现,我从下面mmalc的回答中发现的)。

如果您没有执行上述任何操作,则可能不值得使用NSObjectController。其子类(如NSArrayController)更加有用。

还可以参见这里以讨论您确切的问题!


1
UI元素的绑定可以绑定到对象控制器或其他内容,正如问题所述。那么对象控制器会消除哪些代码呢? - Peter Hosey
你可以在IB中使用NSObjectController来设置绑定的代码。除非我错了,否则你可以在IB中使用非*controller对象来设置绑定?如果是这样,我很乐意接受更正。 - jrturton
1
你不能在IB或nib编辑器中对普通对象设置绑定,但是你可以绑定到普通对象。除了绑定到它之外,创建对象控制器还有什么目的呢?如果没有,为什么不直接将控件绑定到需要支持它的对象上呢? - Peter Hosey
感谢@jrturton给我发送链接。不过,我不知道为什么错过了它...然而,这个问题没有得到完全回答。我希望我们能就这个主题进行更多的讨论。我也不会说NSObjectController可以消除代码。我的上面的例子甚至显示了使用它所创建的轻微开销... - mbpro
谢谢,彼得!这是一个有用的答案。 :) - mbpro
显示剩余2条评论

5

如果我可以直接建立绑定,为什么还需要NSObjectController?

几天前,我在寻找关于NSObjectController的信息时看到了这个问题。今天,当我继续搜索时,我发现以下内容似乎与这个问题相关:

如果绑定的对象实现了NSEditorRegistration,则有一些好处。这是为什么绑定到控制器对象而不是直接绑定到模型的一个好主意的原因之一。NSEditorRegistration允许绑定告诉控制器它的内容正在被编辑。控制器跟踪哪些视图当前正在编辑控制器的内容。例如,如果用户关闭窗口,则与该窗口相关联的每个控制器都可以告诉所有这样的视图立即提交其待处理的编辑,从而用户将不会失去任何数据。苹果提供了一些通用的控制器对象(NSObjectController、NSArrayController、NSTreeController),可以用来包装您的模型对象,提供编辑注册功能。
使用控制器还有一个优点,那就是绑定系统不直接观察您的模型对象,因此如果您用新的模型对象替换了旧的模型对象(例如在详细视图中,用户更改了正在检查的记录),您只需在控制器内部替换模型对象,KVO会注意到并且绑定会更新。

"与该窗口相关联的每个控制器" - 如何将NSObjectControllers与窗口“关联”? - Gannet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接