I have an NSTableView whose NSTableColumn's value is bound to an NSArrayController. The arrayController controls a set of entities in my core data managed object context.
It works well, and when new entities are inserted into the arrayController via UI Actions the tableView selects the new item.
However I would to create new entities into the moc programmatically, then select the new object in the arrayController.
I have tried the following:
Image *newImage = [Image newImage]; // convenience method to insert new entity into mod.
newImage.title = [[pathToImage lastPathComponent] stringByDeletingPathExtension];
newImage.filename = [pathToImage lastPathComponent];
[self.primaryWindowController showImage:newImage];
The showImage: method is as so:
- (void)showImage:(Image *)image
{
[self.imagesArrayController fetch:self];
[self.imagesArrayController setSelectedObjects:@[image]];
}
However, the arrayController doesn't change its selection.
Am I doing it wrong? I assume that the newImage object that I created in the moc is the same as the object that the arrayController is controlling. If that's true, why isn't the arrayController changing its selection?
Hmm - testing that assumption, I have now checked the contents of the arrayController at runtime. The new image is not present - which I assume means that I have 'gone behind the back' of the bindings by manually inserting into the moc...
My newImage convenience method is as so:
+ (Image *)newImage
{
Image *newImage = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:[[CoreDataController sharedController] managedObjectContext]];
return newImage;
}
Is that not KVO compliant?
hmmm - Edit 2...
I assume that it is KVO compliant, as the new image appears in the UI. I'm now thinking that there is a delay between inserting the entity into the moc and the arrayController being informed.
I See from this question New Core Data object doesn't show up in NSArrayController arrangedObjects (helpfully shown to the right of this question by SO) that asking the arrayController to fetch: should help update the arrayController, but that the actual fetch: won't happen until the next time the runloop runs.
Should I delay the selection of the new object using a timer? That seems a little inelegant...
Right - solved it, thanks to this question: New Core Data object doesn't show up in NSArrayController arrangedObjects
I had to call processPendingChanges: on the moc directly after inserting the new object.
So, my new creation convenience method is now:
+ (Image *)newImage
{
Image *newImage = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:[[CoreDataController sharedController] managedObjectContext]];
[[[CoreDataController sharedController] managedObjectContext] processPendingChanges];
return newImage;
}