0
votes

I have an NSTreeController that is getting objects adding to it addObject: method.

I have an NSOutlineView which has its content bound to the NSTreeController's arrangedObjects.

When I delete an object, as below

- (void) deleteSelectionConfirmed {
   id selectedItem = [_outlineView itemAtRow:[_outlineView selectedRow]];
   id obj = ((NSTreeNode *)selectedItem).representedObject;
   NSManagedObjectContext *context = [self managedObjectContext];
   [context deleteObject:obj];
   NSError *error;
   NSLog(@"%hhd", [[self managedObjectContext] hasChanges]);
   if (![context save:&error]) {
     NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
   } else {
        NSLog(@"%@", [_hostController content]);
       [_outlineView reloadData];
   }
    NSLog(@"%hhd", [[self managedObjectContext] hasChanges]);
  }

It doesn't seem to be deleted.

The print out of my treeController content looks as such.

"<Host: 0x6080000b41c0> (entity: Host; id: 0x608000034180 <x-coredata://6E3284F6-D870-4DAF-A4E5-B6A4EB75021E/Host/p131> ; data: {\n    hostname = asdfasdf;\n    index = 0;\n    children = \"<relationship fault: 0x60800022ecc0 'children'>\";\n  title = gggg;\n    username = asdf;\n})",
"<Host: 0x6080002a0960> (entity: Host; id: 0x608000032a80 <x-coredata://6E3284F6-D870-4DAF-A4E5-B6A4EB75021E/Host/p133> ; data: <fault>)"

)

The second line is the 'deleted' object. This is causing issues with the NSOutlineView to display a blank row. If I close an re-open my app however, dumping an NSFetchRequest shows my Managed object was actually deleted, and my NSOutlineView has the intended rows.

Am I missing something? Am I adding objects the wrong way? Should i be using a different binding? Any help is greatly appreciated.

1
How is the tree controller getting its content? Is it bound to the same managed object context as you're manipulating in the above code?Ken Thomases
In the - (void)applicationDidFinishLaunching:(NSNotification *)aNotification NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; for (Host *host in fetchedObjects) { [_hostController addObject:host]; }Kyle Browning
And yes its moc outlet is wired up and set to the same moc as the AppDelegate.Kyle Browning
And is it configured to Entity Name mode and provided with the relevant entity name and fetch predicate? That is, can the tree controller fetch its own content? If not, then you need to manually update its content just like you manually provide it in -applicationDidFinishLaunching:.Ken Thomases
It is set, but unless I manually add the content via addObject: the objects do not show up in the NSOutlineView. How do you manually update the content? When I remove the object from the managed object context and save it, is that not the same thing? Especially since deleteObject: is KVO compliant?Kyle Browning

1 Answers

1
votes

Set the tree controller to automatically prepare its content (using the moc, the entity name, and the fetch predicate). If you do that, you presumably want to remove that code from -applicationDidFinishLaunching:.

From Core Data Programming Guide: Troubleshooting Core Data:

Table view or outline view contents not kept up-to-date when bound to > an NSArrayController or NSTreeController object

Problem: You have a table view or outline view that displays a collection of instances of an entity. As new instances of the entity are added and removed, the table view is not kept in sync.

Cause: If the controller's content is an array that you manage yourself, then it is possible you are not modifying the array in a way that is key-value observing compliant.

If the controller's content is fetched automatically, then you have probably not set the controller to "Automatically prepare content."

Alternatively, the controller may not be properly configured.

Remedy: If the controller's content is a collection that you manage yourself, then ensure you modify the collection in a way that is key-value observing compliant—see “Troubleshooting Cocoa Bindings”.

If the controller's content is fetched automatically, set the "Automatically prepares content" switch for the controller in the Attributes inspector in Interface Builder (see also automaticallyPreparesContent). Doing so means that the controller tracks inserts into and deletions from its managed object context for its entity.

If neither of these is a factor, check to see that the controller is properly configured (for example, that you have set the entity correctly).

So, the tree controller does not track insertions into and deletions from the managed object context unless it is set to automatically prepare content.