使用Interface Builder,NSObjectController子类和绑定时,在模型和视图之间插入控制器逻辑

时间:2012-12-07 11:16:50

标签: objective-c cocoa core-data interface-builder cocoa-bindings

在使用IB,NSObjectController子类和绑定时,我一直在努力理解插入​​控制器逻辑的最佳方法。

我需要在模型和视图之间插入控制器逻辑,我很难找到一种优雅的方法。是的,您可以将操作发送给文件所有者并处理其中的控制器逻辑,但是当某些核心数据模型可以扩展到具有深层关系结构的50个实体或更多实体时,这将开始加载到令人难以置信的锅炉板代码量。

一个非常简单的例子就是这样;想象你有一个具有四个字符串属性的实体myTextWinter,myTextSpring,myTextSummer,myTextAutumn。你有一个通过NSObjectController连接到IB的视图。现在,假设用户可以通过选择菜单中的春,夏,秋,冬来选择他们希望查看的“季节” - 当选择该季节时,我想显示相应季节的文本。

在这个简化的例子中,我可能会获取NSDocument子类中的对象,创建一个名为mySeasonText的属性,我在视图中绑定它,然后检查我的NSUserDefaults以获取适当的季节并将请求路由到适当的属性在模型中。

问题来自于我有50个实体,其中一些有两个,三个或更多深的关系,每个实体都有自己的季节特定文本属性集,我希望在从Season菜单中选择时切换。或者如果我将一堆nsarray控制器链接在一起以访问更深层次的对象。

到目前为止,我一直在做以下事情;在我的每个模型对象中添加一个名为'mySeasonText'的属性,然后从我的控制器设置中获取设置,并路由到适当的季节。每当选择菜单中的新项目时,我都会刷新这些对象。

虽然这样可以消除绝对大量的样板代码,但我的控制器逻辑现在已经在我的模型中了。

一定有更好的方法!有人可以指点我正确的方向吗?

1 个答案:

答案 0 :(得分:2)

这是一个棘手的话题。 Apple甚至在自己的文档中提到了这些挑战:

  

通过使用绑定技术,您可以轻松创建一个Cocoa MVC应用程序,其视图直接观察模型对象以接收状态更改的通知。但是,这种设计存在理论问题。视图对象和模型对象应该是应用程序中最可重用的对象。 [...]在设计方面,最好保持模型和视图对象彼此分离,因为这样可以提高它们的可重用性。

您正在寻找的设计模式是Mediating Controller - 一种使用cocoa-bindings类插入控制器逻辑的方法:

  

中介控制器通常是您从Interface Builder库中拖动的现成对象。您可以配置[中介控制器]以在视图对象的属性和控制器对象的属性之间建立绑定,然后在这些控制器属性和模型对象的特定属性之间建立绑定。结果,当用户改变视图对象中显示的值时,新值通过中介控制器自动传送到模型对象以进行存储。当模型的属性更改其值时,该更改将传递给视图以供显示。

以下是我想要的方式:你有没有看过两个角色需要谈论的电影或电视节目,但他们不会说任何相同的语言?他们找到了其他人(或喜剧中的另外5个人),每个人都有一种共同的语言,他们通过玩一个巨大的翻译电话进行交流。

中介控制器有点像那样。

随着应用程序的增长,他们会学习所有关于在这一个视图中查找这一点的的超级特定规则。这是应用需要运行的代码类型,但是当您将其放入模型中时,您会感觉它是讨厌的

对于几个具体而详细的示例,Apple提供了这个非常详细的文档:Bindings Message Flow

关于这个以及相关的MVC + Bindings的一些非常好的讨论,请参阅: