- My window controller subclass is the nib's owner.
- I instantiate my array controller, in code, in my document subclass. Both the document and window controller use it in code.
- I bind table columns like this: File Owner >> document._arrayController.arrangedObjects.attributeName.
- The table view does not display any rows.
- Neither the window controller nor document class receive
-addObserver
messages related to the table view.
Obviously I'm not binding to this array controller correctly. I think I'm missing something fundamental about how table view columns bind to arrays.
This problem came about during some refactoring. I used to instantiate the array controller in the nib. The document was the file owner, and had an outlet for the array controller. The bindings looked like My Array Controller > arrangedObjects > attributeName. Everything worked fine.
Since the document handles inserting objects through the array controller, I didn't think the window controller should be responsible for creating it. The window controller is the new nib owner, so I removed it from the nib. I now create it in code in -makeWindowControllers
. (I asked this related question about initialization.)
While debugging this I've discovered something else. If the window controller is the table view's data source and I implement -numberOfRowsInDataSource
:
return [[self.document._arrayController arrangedObjects] count];
the table view calls it, sends -addObserver
messages for all the columns, and actually loads values for each cell using the bindings. But when loading a value for a given cell, instead of loading the attribute value for the nth object in arrangedObjects
, it loads attribute values for the entire column of objects. It passes these arrays to value transformers (which can't handle them correctly) and displays the array's description
in the text cells (in which they do not fit).
When the window controller is the table view's data source but columns use bindings, the table view should ignore the result of the -numberOfRowsInTableView
, or perhaps shouldn't call it at all. (Responding to the selector with return 0
merely avoids a runtime error. The data source is only set in the first place to implement tool tips for cells.) And again, all this used to work fine when I created the array controller in the nib.
Some thoughts:
- Is it even possible to use IB to bind table columns to an array controller that's owned by another object?
- Do I need to put the array controller back in the nib, and have the window controller share it with the document instance? (That sounds like horrible design.)
- Should I have two array controllers, one for the window controller and another for the document?
Added:
The reason I used a table view data source along with bindings is to implement drag-and-drop reordering using these methods:
tableView:writeRowsWithIndexes:toPasteboard:
tableView:validateDrop:proposedRow:proposedDropOperation:
tableView:acceptDrop:row:dropOperation: