NSArrayController/NSTreeController 和 Cocoa 视图

Posted

技术标签:

【中文标题】NSArrayController/NSTreeController 和 Cocoa 视图【英文标题】:NSArrayController/NSTreeController and Cocoa Views 【发布时间】:2010-11-22 15:14:25 【问题描述】:

我已经阅读了一段时间的 Objective C 和 Cocoa,我不得不说,虽然我对 Objective-C 的整体简单性感到兴奋,但我对 Cocoa 尤其是 MVC 设计感到完全迷茫图案。我读过的 Cocoa 书籍,要求读者只需完成一组步骤即可让程序运行,而没有对 API 的机制做太多解释。我试图理解 NSTableView、NSOutlineView、它们的数据源、它们的委托的整体含义,以及所有这些与 NSArrayController 和 NSTreeController 等各种控制器类的关系。所以我有几个问题要问:

这些类如何真正互操作? NSTableView 的数据源是 NSArrayController 的实例吗? 在 NSTableView 或 NSOutlineView 中,委托和数据源应该是同一个类吗? 抛开绑定不谈,NSArrayController 和 NSTreeController 还有其他重要的优势吗?

让我们假设有一个容器(在 C 中)包含某种数据(一个 C 结构)。如果数据结构是分层的,我们希望能够在 NSTableView(或 NSOutlineView)中显示这些数据并在运行时交换视图。我应该创建一个具有 NSArrayController(或 NSTreeController)作为实例的类,并包装 C 容器的功能吗?

谢谢你并原谅我的愚蠢问题。

【问题讨论】:

我不会尝试回答,因为我自己对 Cocoa/Objective-C 比较陌生(来自 iPhone 端)。然而,令我震惊的是,您列出的一些问题比 Cocoa 相关的更客观 C。我认为一旦你尝试了一些程序,特别是研究了人们做过的一些其他程序,它就会开始一点一点地“点击”。我认为 Cocoa 是 Objective-C 中一个方便的技巧库,以及一个 OS 特性的包装器。但首先你必须学习并熟悉 Objective-C。 不,它们真的与 Objective-C 无关,这是一种语言。类之间的 MVC 关系是提供这些类的 Cocoa 框架的一部分。 iPhone 上的 Cocoa Touch 也是如此。 【参考方案1】:

这些类如何真正互操作?

考虑使用 TableView 或 OutlineView(任何语言)的传统方式。您通常会实现一个数据源接口,该接口将为视图提供数据。这个数据源实现本质上是一个“控制器”,它将你的数据模型转换为你的表格视图;它还可以处理行选择、插入、删除、排序、过滤等。

现在假设您的应用有许多不同的 TableView,每个都有自己的数据源实现。您会发现每个数据源实现看起来都一样;您可以在数据源之间重用大量代码,因为假设它们使用相同或相似的数据模型,用于排序等的代码也是相同的。

这就是 NSArrayController 的含义:一个通用的 TableView 控制器/数据源。它处理行选择、插入、删除、排序、过滤等,从而使您不必编写一堆样板代码。

NSTableView 的数据源是 NSArrayController 的实例吗?

不,数据绑定取代了传统的数据源接口;因此,NSTableView 使用数据绑定连接到数组控制器。

例如,您可以将表格视图列绑定到模型的属性:

myArrayController.arrangedObjects.firstName 

arrangedObjects 是 NSArrayController 的属性,firstName 是模型的属性。

委托和数据源在 NSTableView 或 NSOutlineView 中应该是同一个类吗?

使用数据绑定时,您无需设置 NSTableView 的数据源。你仍然可以提供一个 NSTableView 委托来自定义视图的外观和行为。 NSArrayController 不是 NSTableView 委托。

当不使用数据绑定时,您必须实现数据源。通常数据源和委托是同一个对象。

【讨论】:

【参考方案2】:

这些不是愚蠢的问题。您提出的问题恰恰是正确的,并且已经深入到如何学习 Cocoa 的核心。先学习MVC,Cocoa是如何实现的,剩下的就清楚了。

虽然逐渐过时,但对于学习 Cocoa 来说,没有比 Aaron Hillegass 的 Cocoa Programming for Mac OS X 更好的书了。如果你有兴趣,我写了更多关于这本书的 cmets last year。还有一些指南(主要针对新 iPhone 开发者)here 和 here。

对于您的具体问题,与其将数据存储在 C 结构中,不如将其存储在 Objective-C 对象(模型对象,MVC 中的“M”)中。

然后构建一个 Controller 类作为 NSOutlineView(专为分层数据设计)的数据源。目前,避免使用以“Controller”结尾的 Cocoa 类。这些与绑定有关(主要用于核心数据)。虽然非常强大,但它们比你一开始想深入研究的要多(即使经过多年的 Cocoa 编程,我也只对某些目标问题使用绑定;如果它们很复杂,它们会使你的程序很难维护) .你的控制器现在应该是 NSObject 的子类。它将实现 NSOutlineViewDataSource 方法。如果您需要委托,将同一个对象作为数据源和委托是很常见且自然的。

【讨论】:

【参考方案3】:

Delegate 是当视图发生有趣的事情时接收回调的对象。

数据源与委托非常相似——它也接收回调,但只接收与获取表数据相关的回调。

它们不必相同(您可能有可以对任何数据源进行操作的控制器/委托),但实际上它们通常是同一个对象,因为提供数据并对其进行操作很方便同一个班级。

如果不适合您的程序,您根本不需要使用NSArrayController。任何类都可以是委托(它是非正式协议,这意味着您不需要声明任何接口,也不需要继承任何基类),您可以简单地编写自己的委托方法。

【讨论】:

以上是关于NSArrayController/NSTreeController 和 Cocoa 视图的主要内容,如果未能解决你的问题,请参考以下文章