代码之家  ›  专栏  ›  技术社区  ›  Andy

使用来自多个XIB的一个NSArrayController

  •  3
  • Andy  · 技术社区  · 16 年前

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

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

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

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

    问题是我不知道如何在Interface Builder中实现这一点。我无法将一个NSArray控制器绑定到另一个NSArray控制器(我收到一个运行时错误,表明它只能绑定到一个NSArray)。将NSArrayController连接到文件所有者的NSArrayController成员也不会有任何帮助,因为这只会清除我希望它使用的NSArrayController。

    我想我可以自己在代码中设置绑定,但如果可能的话,似乎最好使用Interface Builder。在Interface Builder中是否有这样做的方法,或者是否有更好的方法一起进行设置?

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

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

    通常,我会从“绑定到”组合框中选择NSArrayController,将arrangedObjects用作控制器键,将属性本身用作模型键路径。我不知道在这种情况下如何做到这一点——如果我能做到的话。

    在上述过程中我做错了什么吗?

    4 回复  |  直到 15 年前
        1
  •  1
  •   Andy    16 年前

    我能想到的最好的选择就是通知第二个 NSArrayController 它所管理的阵列已通过调用 rearrangeObjects: 在上面。这看起来很笨重,但很管用。

        2
  •  1
  •   Ryan Townshend    16 年前

        3
  •  1
  •   Tom Dalling    15 年前

    将阵列添加到时,您可以通过KVO使两个NSArrayController更新。诀窍在于,您必须以符合KVO的方式观察并添加到阵列中。

    您可能需要某个拥有该数组的对象,我们称之为“模型”。数组必须是对象上的一个键,我们将该键称为“contentArray”。接下来,当您添加到或从中删除时,您应该首先调用“model”上的mutableArrayWorkey以获取“contentArray”。然后,从阵列中添加/删除操作应该有效,例如:

    Controller1绑定到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"];
    }
    
        4
  •  0
  •   Chuck    16 年前

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