【问题标题】:NSTableView backed by NSArrayController: why does setContent: work while IB doesn't?由 NSArrayController 支持的 NSTableView:为什么 setContent: 工作而 IB 不工作?
【发布时间】:2011-12-18 04:50:16
【问题描述】:

我正在尝试实现将 NSTableView 绑定到 NSArrayController 的最简单的情况,以便 NSTableView 由 NSArray 支持。

设置如下:

  1. 我有一个 NSArrayController,它的“内容数组”绑定到我的应用委托中的 NSArray。
  2. 在 NSArrayController 的“Object Controller”中,类名设置为 Model,即 NSArray 中包含的对象类型。
  3. NSTableView 单列的 'Value' 绑定到 Array Controller 的 'arrangedObjects' 的 key 'name',这是 Model 类的唯一字段。
  4. 在我的应用委托的 applicationDidFinishLaunching: 中,我初始化了 NSArray,并插入了一些模型对象。

但是,与 Model 对应的行不会出现在表中,除非我也这样做:[self.arrayController setContent: self.array]

有没有一种方法可以使用在 Interface Builder 中连接的绑定来使其工作?我原以为 NSArrayController 的“内容数组”直接绑定到 NSArray 意味着我不必以编程方式设置内容。知道为什么会帮助我更好地理解绑定。

【问题讨论】:

    标签: cocoa binding nstableview nsarraycontroller


    【解决方案1】:

    您的数组控制器正在观察您的 App Delegate 的“数组”属性。这意味着 KVO 通知仅在设置数组对象时发送,而不是在添加对象时发送。听起来您正在使用 NSMutableArray 并向其中添加对象,这就解释了为什么 Array Controller 没有收到更改通知,因为底层对象没有更改。

    简单的解决方案是将您的调用包装在一个 will/did 更改块中,如下所示:

    [self willChangeValueForKey:@"array"];
    [self.array addObject:[NSDictionary dictionaryWithObject:@"foo" forKey:@"name"]];
    [self.array addObject:[NSDictionary dictionaryWithObject:@"bar" forKey:@"name"]];
    [self didChangeValueForKey:@"array"];
    

    这会手动通知观察者“数组”属性发生了变化。

    长答案:你做错了。拥有数组控制器的全部意义在于将管理数组的工作转移到控制器类本身,因此它可以管理底层数组、发送正确的通知、维护状态等,而您不必费心执行实现细节。更好的解决方案是解开内容数组绑定,直接将对象添加到数组控制器,如下所示:

    [arrayController addObject:[NSDictionary dictionaryWithObject:@"foo" forKey:@"name"]];
    [arrayController addObject:[NSDictionary dictionaryWithObject:@"bar" forKey:@"name"]];
    

    这是因为数组控制器在内部管理自己的数组。

    最好的解决方案是使用 Core Data。 NSArrayController 旨在与它一起使用。您还可以免费获得一大堆东西,例如持久化、撤消支持、对象关系,以及无需编写代码即可添加对象的能力,只需直接从您的 UI 控件调用数组控制器上的add:

    【讨论】:

    • 谢谢。我不清楚 NSArrayController 是简单地管理一个数组,还是一个数组的代理。从你的回答看来是后者。
    • 拥有那个绑定绝对没问题,而且它没有错。是的——数组控制器处理数组内容。但是如果你想保存/恢复对象呢?这不是由阵列控制器完成的(除非绑定到NSUserDefaults)。使用绑定和您的 KVO 解决方案时,您可以在关闭窗口时保存并在打开窗口时恢复,例如– 多么方便!
    猜你喜欢
    • 2013-07-01
    • 2017-07-28
    • 1970-01-01
    • 2019-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    相关资源
    最近更新 更多