在单独的NIB文件中的多个视图之间共享NSArrayController

时间:2011-03-29 18:26:46

标签: cocoa

首先,一些背景知识:我正在尝试在Cocoa中实现一个master-detail接口(对于OS X)。也就是说,我有一个带有两个NSTableView的窗口,它显示两种不同类型的对象。对于这个问题,让我们说它们是仓库和包(选择一个类似于我实际问题的例子。)在第一个表视图中选择一行(在仓库中)将显示属于该仓库的包列表第二个表视图。对于模型部分,我目前有一个NSMutableArray仓库对象仓库,每个仓库对象都有NSArray个包对象。需要注意的一点是,在加载NIB文件后会修改仓库变量,因此必须通知NSArrayController

现在,我试图组织它,以便“master”在它自己的视图对象中,“detail”在它自己的视图对象中。这意味着有三个NIB:WarehousesView NIB,WarehouseDetailView NIB和MainWindow NIB。

  • WarehousesView NIB包含一个WarehousesViewController实例(来自NSViewController的子类)和视图本身。
  • WarehouseDetailView NIB包含WarehouseDetailViewController的实例和视图本身。
  • MainWindow NIB包含主窗口,MainWindowController的实例以及WarehousesView和WarehouseDetailView的实例。窗口本身包含NSSplitView,拆分视图的视图连接到NIB文件中的相应视图实例。

这让我想到了问题的前半部分:

1)这是分割Cocoa应用程序的应用程序视图的好方法吗?对我来说这是有道理的,因为稍后可以将更多关于仓库的详细信息添加到WarehouseDetailView中。

这是一个重要的问题,因为如果我跳过创建视图,将所有控件直接放在窗口中并将其他所有内容(包括与仓库和包对应的NSArrayController实例)放入同一个NIB文件中,一切正常。我不需要问问题的后半部分我是否应该这样做。

问题的后半部分基本上是:

2)如果我按照上面的描述拆分它,那么我应该在哪里放置与仓库和包相对应的NSArrayController,以便主 - 细节界面仍然有效?目前我正在使用Cocoa绑定,所以仓库NSArrayController的内容数组需要绑定到我的仓库数组,而包NSArrayController的内容数组需要绑定到仓库的选择{ {1}}

我尝试了一些事情,但我完全无法完成任何工作。具体来说,我已经尝试将仓库的NSArrayController放入WarehousesView NIB,将仓库的NSArrayController放入WarehouseDetailView NIB。这种方法的问题在于我无法找到将包NSArrayController绑定到仓库NSArrayController的选择的方法。我尝试过的另一件事是(1)将两个NSArrayController放入MainWindow NIB,(2)将那些NSArrayController连接到MainWindowController中的IBOutlets,然后(3)将这些变量传递给它们各个视图控制器通过它们的构造函数,(4)通过KVC将它们作为视图控制器中的属性公开,以及(5)通过文件所有者将视图中的必要表列绑定到数组控制器。结果是没有出现,但也没有错误。如果其中一种方法是首选方法,我可以提供更多详细信息,以帮助查看我是否做错了。

提前致谢!

编辑:我确实看过this related question,如果我理解正确的话,他们似乎正在为每个NIB文件使用NSArrayController s的单独实例,而这似乎没有意义从设计的角度来看,但也许我错了?

1 个答案:

答案 0 :(得分:1)

第1部分:你当然可以这样做。我会说这是一个偏好问题。就个人而言,如果要在窗口中同时显示视图,我会将它们保存在同一个笔尖中。*模块化也是一件好事。

第2部分:您可以将阵列控制器放在任何您喜欢的位置。您唯一需要担心的是让每个对象获得您希望它拥有的信息所需的引用。如果你想要我的2¢,我会说在视图中将每个放在视图中,其内容将显示在其中。这将使您的详细视图设置更加困难,但它继续您似乎要采用的模块化。 / p>

你必须记住,笔尖中的每个对象都是一个真实的实例。笔尖为你分配并为它们分配;如果你在一个笔尖中放置一个MyClass对象,在另一个笔尖放置一个MyClass对象,那些两个 不同的对象。对于笔尖来说,这有时是一个棘手的问题:为你自动创建实例真的很方便,但是当你想跨nib做事时,这也意味着一些摆弄引用。

听起来你将WarehouseViewWarehouseDetailView的实例放入你的单个nib和MainMenu.nib中,并期望它们是相同的对象。事实并非如此。您必须将笔尖中的对象链接到他们已经知道的对象。你必须为你的特殊情况解决这个问题。

我不知道你的模型存储在哪里,或者你是如何加载nib的。但是,无论它加载哪个对象,都可能是您在单个笔尖和应用程序其余部分之间的链接。这就是nib中文件所有者代理对象的用途 - 它为你提供了一个将nib中的对象连接到他们不会知道的代码的地方。


*:如果你发现如果它们没有包含在IB的拆分视图中,你可以更容易地布局视图,你可以自己设置它们:将自定​​义视图对象放在MainMenu.xib窗口中,你可以打开每个视图都在自己的IB窗口中(虽然它不会在应用程序的窗口中)。然后将分割视图的子视图设置为awakeFromNib