使用来自多个XIB的一个NSArrayController

时间:2009-01-17 19:55:15

标签: objective-c cocoa interface-builder cocoa-bindings nsarraycontroller

我在使用不同XIB定义的两个窗口中显示一个NSArrayController的内容时遇到一些问题。

在我的主窗口(在MainMenu.xib中)中,我有一个绑定到NSArrayController的NSTableView

在我的第二个XIB中,我有另一个包含NSTableView的窗口。我创建了一个新的NSArrayController,并将表绑定到该NSArrayController的内容。

两个NSArrayControllers都绑定到完全相同的NSArray。

一开始一切都很好,但问题是如果在主窗口中使用NSArrayController将对象添加到数组中,则不会更新辅助窗口的数据视图。这很可能是因为它不知道它需要自我更新,因为它的NSArrayController不用于添加新对象。

我想要做的是在两个窗口中使用完全相同的NSArrayController实例。这样,如果将对象添加到数组中,则会通知两个视图更改。

问题是我无法弄清楚如何在Interface Builder中执行此操作。我无法将NSArrayController绑定到另一个NSArrayController(我得到一个运行时错误,指示它只能绑定到NSArray)。将NSArrayController连接到File的Owner的NSArrayController成员也无济于事,因为那只会消灭我想要它使用的NSArrayController。

我想我可以在代码中自己设置绑定,但是如果可能的话,似乎最好使用Interface Builder。有没有办法在Interface Builder中执行此操作,或者更好的方法可以将它们组合在一起?

更新:为回应Chuck的回答和评论,我尝试了以下方法: - 将我的NSTableView的表内容绑定到NSArrayController成员的arrangeObjects(如果我使用了NSArrayController本身,日志中出现错误:“[NSArrayController count]:发送到实例的无法识别的选择器”) - 将表中的每一列绑定到文件的所有者,其模型键路径为arrayController.arrangedObjects.propertyName

这仍然没有导致表的内容获得更新。我想这是因为我绑定了NSArrayController的arrangeObjects,而不是NSArrayController本身。但是,如果我直接绑定到NSArrayController,那就会给我带来错误。

通常,我会从“Bind to”ComboBox中选择我的NSArrayController,使用arrangeObjects作为Controller Key,将属性本身作为Model Key Path。我不确定在这种情况下如何做到相同 - 如果我可以的话。

我在上面的过程中做错了什么?

4 个答案:

答案 0 :(得分:1)

我能够提出的最佳选择是通过调用NSArrayController来通知第二个rearrangeObjects:它所管理的阵列已更改。这似乎很笨重,但它确实有效。

答案 1 :(得分:1)

如何在IB中将它们设置为代理对象,然后在代码中实例化实际代码?

答案 2 :(得分:1)

添加数组时,可以通过KVO更新两个NSArrayControllers。诀窍是你必须以符合KVO的方式观察和添加数组。

你想要一些拥有该数组的对象,我们称之为“模型”。数组必须是对象的键,让我们调用键“contentArray”。接下来,当你添加/删除时,你应该首先在“model”上调用mutableArrayForKey来获取“contentArray”。然后从数组中添加/删除应该有效,例如:

Controller1绑定到self.model.contentArray

Controller2绑定到self.model.contentArray

//this method is on the "model" object
-(void)addContent(id content)
{
    NSMutableArray* contentArr = [self mutableArrayForKey:@"contentArray"];
    [contentArr addObject:content]; //this will trigger KVO notifications
}

或者你可以像这样手动执行KVO通知:

-(void)addContent(id content)
{
    [self willChangeValueForKey:@"contentArray"];
    [m_contentArray addObject:content];
    [self didChangeValueForKey:@"contentArray"];
}

答案 3 :(得分:0)

当您通过另一个更新时,没有理由让两个阵列控制器使一个视图不更新。如果没有发生,听起来你的KVO通知会在某处丢失。您很可能直接编辑数组(在NSArrayController子类的add:方法中,也许?)而不发送正确的更改通知。