views:

225

answers:

3

Hi, i've been reading for a while a little bit of Objective C and Cocoa, and i have to say that although i am thrilled with the overall simplicity of Objective-C, I feel totaly lost regarding Cocoa and especially the MVC design pattern. The Cocoa books I've read, ask the reader to just complete a set of steps for a program to work, without doing much explanation about the mechanisms of the API. I am trying to understand the overall meaning of NSTableView, NSOutlineView, their datasources, their delegates, and what all these have to do with the various controller classes like NSArrayController and NSTreeController. So i have a couple of questions to ask:

  • How do these classes really interoperate ?
  • Is the datasource of an NSTableView an instance of an NSArrayController ?
  • Should a delegate and a datasource be the same class in a NSTableView or NSOutlineView ?
  • Leaving binding aside, do NSArrayController and NSTreeController have any other important advantage ?

Let's assume that there is a container (in C) with some sort of data (a C struct). We want to be able to show these data in an NSTableView (or NSOutlineView) and to exchange views at runtime, if the data structure is hierarchical. Should i create a class that has an NSArrayController (or NSTreeController) as instance, and wrap the functionality of the C container ?

Thank you and forgive me for my silly questions.

A: 

Delegate is object that receives callbacks when something interesting happens with the view.

Datasource is very similar to delegate - it also receives callbacks, but only those related to getting data for the table.

They don't have to be the same (you might have controller/delegate that can operate on any data source), but in practice they're usually the same object, because it's convenient to provide data and operate on it in the same class.

You don't need to use NSArrayController at all, if that doesn't fit your program. Any class can be a delegate (it's informal protocol, meaning you don't need to declare any interface nor inherit any base class), you can simply write your own delegate methods.

porneL
+2  A: 

These are not silly questions. You're asking precisely the right questions, and have gone to the heart of how to learn Cocoa. Learn MVC first, and how Cocoa implements it, and the rest will be clear.

While slowly becoming dated, there is still no better book for learning Cocoa than Cocoa Programming for Mac OS X by Aaron Hillegass. I wrote up some more comments about this book last year if you're interested. And some more guides (mostly targeted at new iPhone developers) here and here.

To your specific question, rather than store the data in a C struct, store it in an Objective-C object (a model object, the "M" in MVC).

Then build a Controller class to be the datasource for the NSOutlineView (which is designed for hierarchical data). For the moment, avoid Cocoa classes that end in "Controller." These are related to bindings (and mostly used for Core Data). While very powerful, they're more than you want to dive into at the beginning (and even after years of Cocoa programming, I only use bindings for certain targeted problems; they can make your programs very hard to maintain if they're complicated). Your controller for now should be a subclass of NSObject. It will implement the NSOutlineViewDataSource methods. If you need a delegate, it is common and natural to make the same object be the datasource and delegate.

Rob Napier
A: 

How do these classes really interoperate ?

Consider the traditional way using a TableView or OutlineView (in any language). You typically implement a data source interface that will provide data for the view. This data source implementation is essentially a "controller" that translates your data model to your table view; and it can also handle row selection, inserting, deleting, sorting, filtering, etc.

Now say your app has a number of different TableViews, each with its own data source implementation. You'll find that each data source implementation starts to look the same; you'd be able to reuse a lot of the code between your data sources, because assuming they're working on the same or similar data models, the code for sorting etc. is also the same.

That's what NSArrayController is: a generic TableView controller/data source. It handles row selection, inserting, deleting, sorting, filtering, etc. thereby saving you from having to write a bunch of boilerplate code.

Is the datasource of an NSTableView an instance of an NSArrayController ?

No, data bindings replace the traditional data source interface; therefore, the NSTableView is connected to the array controller using data bindings.

For example, you would bind a table view column to a property of your model:

myArrayController.arrangedObjects.firstName

where arrangedObjects is a property of NSArrayController and firstName is a property of your model.

Should a delegate and a datasource be the same class in a NSTableView or NSOutlineView ?

When using data bindings you do not set the NSTableView's data source. You may still provide an NSTableView delegate to customize the look and behavior of the view. NSArrayController is not an NSTableView delegate.

When not using data bindings then you must implement a data source. Often the data source and the delegate are the same object.

Darren