1

I’m trying to create a view-based NSTableView, populated via Cocoa bindings.

My NSArrayController is pointing to the jobs array property of the currentUser property of the application delegate, like so:

binding 1

I expect each model in that array to be of class HSJob:

binding 2

However, once I’m binding my table view to the NSArrayController, its arrangedObjects property for some reason thinks it belongs to class HSJob (I’m expecting an NSArray).

binding 3

Obviously, this doesn’t let me link individual cell content to Job object properties and I can’t display anything in my table view:

binding 4

So what am I doing wrong here?

Update

I even decided to go as far as implementing some manual value update notifications + moving everything into the AppDelegate, just to experiment. Here, I changed my own HSJob class for just some NSDictionaries.

AppDelegate.h

@property NSArray *things;

AppDelegate.m

@synthesize things = _things;

- (NSArray *)things {
    if (!_things)
        return @[@{@"name": @"Default Thing"}];
    else
        return _things;
}

- (void)setThings:(NSArray *)things {
    [self willChangeValueForKey:@"things"];
    _things = things;
    [self didChangeValueForKey:@"things"];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    [self setThings:@[@{@"name": @"Actual Thing"}]];

}

Only “Default Thing” ever gets displayed. Even though I’m setting a new value to the things property right after the application launch, that array never gets displayed.

Arnold
  • 2,390
  • 1
  • 26
  • 45
  • Looks fine to me. InterfaceBuilder completions don't work terribly well. Just manually enter the property and all will work. BTW you can leave out `self.` in that first screenshot. – Gerd K Oct 02 '13 at 04:32
  • Gerd K, no, the point is, it still doesn’t work either. Doesn’t even generate any table cells, let alone populate them. – Arnold Oct 02 '13 at 04:33
  • Are you certain `jobs` actually has any content? – Gerd K Oct 02 '13 at 04:35
  • @GerdK, yes, I am, I use it to populate NSTextField autocomplete in other parts of the application. The `jobs` content is fetched asynchronously though, after the app is launched. Could that be the problem? – Arnold Oct 02 '13 at 04:36
  • If it is set in Key-Value-compliant ways that should not be a problem. If it is a mutable array that you add values to, that will not work though, at least not without additional code. – Gerd K Oct 02 '13 at 04:40
  • It’s not, `currentUser.jobs` is a an `NSArray` property, populated via the setter. So yeah, there doesn’t seem to anything wrong there. – Arnold Oct 02 '13 at 04:42
  • Sorry, my bad. Do not bind the table's `content` binding, instead bind the table columns to the array controllers objects. – Gerd K Oct 02 '13 at 04:56
  • @GerdK, but I’m using a view-based table view. For view-based table views, the table’s own `content` is expected to be bound to the `arrangedObjects`: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TableView/PopulatingViewTablesWithBindings/PopulatingView-TablesWithBindings.html – Arnold Oct 02 '13 at 05:04
  • Actually either works. Did you double-check `currentUser`? Is it set in a KVC-compliant manner? – Gerd K Oct 02 '13 at 05:17
  • @GerdK, I’ve double checked it and couldn’t find anything wrong. I also decided to experiment with just a plain array property on the AppDelegate, populated with some dictionaries. See the update for the results. – Arnold Oct 02 '13 at 06:37

2 Answers2

1

What you "did wrong" was to create an app delegate object in a XIB other than MainMenu.xib, and then assume that it's [NSApp delegate]. What you actually get is a totally separate object of your app delegate class with its own properties, just for that xib. So the object attached to your XIB never runs applicationDidFinish launching because it is not your app's delegate.

I suggest a solution by modifying the init for your app delegate class here: https://stackoverflow.com/a/22873562/3120884

MainMenu.xib gets away with having an App Delegate object because as the NSMainNib designated in Info.plist, it gets special treatment in NSApplicationMain, which does hook up that Interface Builder object to [NSApp delegate].

Community
  • 1
  • 1
stevesliva
  • 5,351
  • 1
  • 16
  • 39
0

I managed to fix this by binding my NSArrayController to Application instead of the manually created AppDelegate object. Therefore, the Model Key Path is now:

self.delegate.currentUser.jobs

Obviously this doesn’t get autocompleted by Xcode and it still complains about not being able to resolve the path, but it works anyway.

The reason why my AppDelegate object in the Xib wasn’t working is still a mystery, but it may have something to do with the fact that the Xib in question wasn’t the default MainMenu.xib, but a custom NSPanel attached to a controller.

Arnold
  • 2,390
  • 1
  • 26
  • 45