/dev/trouble
Eric Roller's Development Blog

On Mac OS X 10.5 (Leopard) it appears to work fine, but when I quit my app, on a machine running 10.4 (Tiger), these messages appear in the Console:

2009-03-03 21:49:10.680 MyApp[6793] *** Illegal NSTableView data source
    (). Must implement numberOfRowsInTableView: and
    tableView:objectValueForTableColumn:row:
2009-03-03 21:49:23.139 MyApp[6793] *** -[NSCFString count]:
    selector not recognized [self = 0x1bc7f00]
2009-03-03 21:49:23.140 MyApp[6793] Exception raised during posting
    of notification.  Ignored.  exception: *** -[NSCFString count]:
    selector not recognized [self = 0x1bc7f00]

The interesting fact is that the MyApp class is the delegate of the NSTableView since it implements support for drag & drop. However, it is not designed to be the data source for the NSTableView. Instead, I use an NSArrayController through a binding in the NSTableView instance. This works fine until one quits.

What I suspect is happening (on Tiger) is that the NSArrayController is purged before the NSApp, which suddely remains as the only data source of the NSTableView, but without the access methods implemented.

The solution would be to implement dummy methods in the MyApp class for numberOfRowsInTableView: and tableView:objectValueForTableColumn:row: where one returns 0 and nil, respectively.

There does not appear to be a way to easily define a double-click action for an NSTableView in Interface Builder. The best solution that I have found is via a custom table view class and a dummy action. This requires that the target is available in the nib file, e.g. the window controller or a custom array controller of the table view.

Step one: control-drag a target/action-connection from the table view to the target where the double-click action is defined, but select a different action method, at best a bogus method that does nothing (I like to use "noAction:" for such purposes).

awakeFromNib method to assign a double-click action.

+ (void) awakeFromNib
{
    NSAssert1([[self target] isKindOfClass:[Duck class]],
            @"The target of MyTableView should be Duck, not %@.",
            [[self target] class]);

    // Let our drag-and-drop array controller, i.e. the Duck,
    // handle double-clicks to the cells in the table view.
    [self setDoubleAction:@selector(doubleClick:)];

    // We no longer need the dummy action (noAction:)
    [self setAction:NULL];
}