更新绑定到 NSArrayController 的表列

发布于 2024-08-29 13:01:10 字数 1212 浏览 1 评论 0原文

我对可可绑定的世界相当陌生,并且遇到了一些麻烦(也许/可能是由于误解)。

我有一个单例,其中包含一个名为plugins 的NSMutableArray,其中包含Plugin 类的对象。它有一个名为 loadPlugins 的方法,它将对象添加到插件数组中。这可以在任何时候调用。它已作为实例添加到 Interface Builder 中。

IB 中还有一个 NSObjectController,其内容出口连接到单例。还有一个 NSArrayController,其 contentArray 绑定到 NSObjectController(控制器键是“selection”,模型键路径是“plugins”,对象类名称是“Plugin”)。

最后,我有一个包含 2 列的表视图,其值使用 Plugin 类中的属性键绑定到 NSArrayController 的排列对象。

到目前为止是标准的(至少据我从教程中可以看出)。我的问题是,当在单例中调用 loadPlugins 方法并将对象添加到插件数组中时,表不会更新以显示对象(除非在加载 nib 之前调用 loadPlugins )。在 tableView 上调用的 -reloadData 不会执行任何操作。

有没有办法告诉 NSArrayController 引用的数组已更新?我知道 NSArrayController 有 -add: 方法,可以在 loadPlugins 中使用,但这并不理想,因为我想让单例与显示方面完全分开。

这似乎与: 刷新 Cocoa-Binding - NSArrayController - ComboBox

行:“编辑控制器后面的数组back”似乎可能指出了问题,但我希望单例可以不知道控制器。

提前致谢。

\编辑...

根据 TechZen 的建议,以下是绑定:

TableColumn --('arrangedObjects', 'pluginName', Value)--> NSArrayController
NSArrayController --('selection', 'plugins', ContentArray)--> NSObjectController
NSObjectController --(content)--> PluginsManager

I'm fairly new to the world of bindings in cocoa, and I'm having some troubles (perhaps/probably due to a misunderstanding).

I have a singleton that contains an NSMutableArray called plugins, containing objects of class Plugin. It has a method called loadPlugins which adds objects to the plugins array. This may be called at any point. It's been added as an instance in Interface Builder.

Also in IB is an NSObjectController, whose content outlet is connected to the singleton. There is also an NSArrayController, whose contentArray is bound to the NSObjectController (controller key is 'selection', model key path is 'plugins', object class name is 'Plugin').

And finally I have a table view with 2 columns, the values of which are bound to the NSArrayController's arrangedObjects, using keys of properties in the Plugin class.

So far so standard (as far as I can tell from tutorials at least). My trouble is that when the loadPlugins method is called in the singleton, and objects are added to the plugins array, the table doesn't update to show the objects (unless loadPlugins is called before the nib is loaded). -reloadData called on the tableView doesn't do anything.

Is there a way to tell the NSArrayController that the referenced array has been updated? I understand there is the -add: method for NSArrayController, which could be used in the loadPlugins, but this isn't desirable as I want to keep the singleton totally separate from the display aspect.

This seems related to:
Refresh Cocoa-Binding - NSArrayController - ComboBox

The line: "editing the array behind the controller's back" seems to perhaps pinpoint the problem, but I would hope that it would be possible to have the singleton not know about the controller.

Thanks in advance.

\edit...

As per TechZen's suggestion, here's the bindings:

TableColumn --('arrangedObjects', 'pluginName', Value)--> NSArrayController
NSArrayController --('selection', 'plugins', ContentArray)--> NSObjectController
NSObjectController --(content)--> PluginsManager

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤凫 2024-09-05 13:01:10

作为让它工作的一种有点黑客的方法(通过触发适当的 KVO 通知),请尝试放置:

[self willChangeValueForKey:@"plugins"];
[plugins addObject:somePlugin];
[self didChangeValueForKey:@"plugins"];

理想情况下

[plugins addObject:somePlugin];

,您应该实现完整的 KVC 支持,然后您可以使用 KVC 触发 KVO,这将触发绑定更新。如果您这样做了,则可以使用:

[self insertObject:somePlugin inPluginsAtIndex:0];

有关 KVC 合规性所需的信息,请阅读以下内容:http://developer.apple.com/mac/library/documentation/cocoa/conceptual/KeyValueCoding/Concepts/Compliant.html

As a somewhat hacky way to get it working (by triggering the appropriate KVO notification), try putting:

[self willChangeValueForKey:@"plugins"];
[plugins addObject:somePlugin];
[self didChangeValueForKey:@"plugins"];

Instead of

[plugins addObject:somePlugin];

Ideally you should implement full on KVC support, then you can use KVC to trigger KVO which will trigger the Bindings update. If you did that, you could then use:

[self insertObject:somePlugin inPluginsAtIndex:0];

For info on what is required for KVC compliance, read this: http://developer.apple.com/mac/library/documentation/cocoa/conceptual/KeyValueCoding/Concepts/Compliant.html.

2024-09-05 13:01:10

我已经弄清楚了这一点 - 这是RTFM(以及理解-TFM)的经典案例。一切都归结为 确保 KVC 合规性

在 PluginManager Singleton 中,它有一个名为“plugins”的数组,我只需要实现:

-insertObject:inPluginsAtIndex:
-removeObjectFromPluginsAtIndex:

然后当我想要添加/删除插件时使用这些方法。

谢谢你们的帮助。

I've figured this out - it was a classic case of RTFM (and Understand-TFM). All came down to ensuring KVC compliance.

In the PluginManager Singleton, which had the array called 'plugins', I simply needed to implement:

-insertObject:inPluginsAtIndex:
-removeObjectFromPluginsAtIndex:

And then use those methods when I wanted to add/remove a plugin.

Thanks for the help guys.

孤独陪着我 2024-09-05 13:01:10

有没有办法告诉
引用的 NSArrayController
数组已更新?

你不应该这样做。这就是键值观察的目的。它是整个绑定功能的基础。绑定对象(在本例中为界面元素)自动观察(接收通知)它观察到的对象已更改。您不必手动告诉它发生了更改。如果表没有更新,则绑定是错误的。

从文字描述中很难看出,但我认为你的问题是你将 NSObjectController 设置为“选择”。仅当您将另一个 UI 元素绑定到 NSObjectController 并且该元素选择控制器中的数据项时,这才有效。

您可以尝试写出类似这样的绑定:

Object1--(controller key, key path, class)--> Object2 
Object2--(controller key, key path, class)--> Object3

您可能会看到问题,如果您将其发布,我们其他人就可以理解它。

(需要有一个以文本方式表示绑定和核心数据关系的标准,但我想我们会蒙混过关。)

Is there a way to tell the
NSArrayController that the referenced
array has been updated?

You shouldn't have to. That is what key-value observing is for. It is the basis of the entire binding functionality. The bound object (in this case the interface element) automatically observes (receives a notification) that the object it observes has changed. You shouldn't ever to have to manually tell it that a change has taken place. If the table does not update then the binding is wrong.

It's hard to tell from a textual description but I think your problem is that you have the NSObjectController set to "selection". That will only work if you've bound another UI element to the NSObjectController and that element selects a data item in the controller.

You might try writing out the bindings something like:

Object1--(controller key, key path, class)--> Object2 
Object2--(controller key, key path, class)--> Object3

You might see the problem and if you post it the rest of us can understand it.

(There needs to be a standard for representing bindings and Core Data relationships textually but I guess we'll muddle through.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文