I am trying to implement pretty much the simplest case of binding a NSTableView to a NSArrayController, so that the NSTableView is backed by an NSArray.
Here is the setup:
However, the rows corresponding to Model do not appear in the table unless I also do: [self.arrayController setContent: self.array]
.
Is there a way I can get this to work using bindings wired up in Interface Builder? I would have expected the fact that the NSArrayController's 'Content Array' is bound directly to the NSArray to mean that I wouldn't have to set the content programmatically. Knowing why would help me understand bindings better.
Your array controller is observing your App Delegate's "array" property. That means KVO notifications are sent only when the array object is set, not when objects are added to it. It sounds like you are using an NSMutableArray and adding objects to it, which explains why the Array Controller is not being notified of changes, because the underlying object is not changing.
The easy solution is to wrap your calls in a will/did change block like so:
[self willChangeValueForKey:@"array"];
[self.array addObject:[NSDictionary dictionaryWithObject:@"foo" forKey:@"name"]];
[self.array addObject:[NSDictionary dictionaryWithObject:@"bar" forKey:@"name"]];
[self didChangeValueForKey:@"array"];
This manually notifies observers that there has been a change to the "array" property.
Long answer: You're doing it wrong. The whole point of having an array controller is to shift the work of managing the array to the controller class itself, so it manages the underlying array, sends out the right notifications, maintains state, etc. without you having to sweat the implementation details. A better solution would be to unhook the content array binding and just add objects to the array controller directly like so:
[arrayController addObject:[NSDictionary dictionaryWithObject:@"foo" forKey:@"name"]];
[arrayController addObject:[NSDictionary dictionaryWithObject:@"bar" forKey:@"name"]];
This works because the array controller manages its own array internally.
The best solution is to use Core Data. NSArrayController is designed to be used with it. You also get a whole bunch of things for free, like persistentce, undo support, object relationsips, and the ability to add objects without writing code just by calling add:
on the array controller directly from your UI controls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With