I am trying to work out an issue with undo in a few places in my application, and think 
if I "get it" with one of the places, I should be able to apply the same theory 
elsewhere.

I have a parent and children relationship, and need to have a few things happen 
during the process of adding and deleting a child so that the rest of the 
application stays in sync. The core data side of things manages the undoability 
of the data, but of course it doesn't know how to send the other messages at 
the right times, so I have tried to add the notification messages in the 
reverse order on the undo stack (prepareWithInvocationTarget), but then redo 
doesn't work properly All the undo and redo for the rest of my application is 
working fine (just fairly simple relationships and attributes), but I think 
there's a design pattern I'm missing here for the more complex case.

It's probably best for me to just post the things that need to happen during a 
normal add of a child and deletion of a child, and hopefully someone will be 
able to give me guidance on how to make it undoable and redoable.

- (MyNode *)createChild {
        MyNode *child = [NSEntityDescription 
insertNewObjectForEntityForName:@"MyNodeEntity" inManagedObjectContext:[self 
managedObjectContext]];
    
        // Set a bunch of properties on the new child.
        ...

        [[self mutableSetValueForKey:@"children"] addObject:child];
        
        // Set a bunch more properties on the new child and other core data 
managed objects
        ...

        // Let the front end of the application know about it

        [[NSNotificationCenter defaultCenter] 
postNotificationName:@"ChildNodeAddedNotification" object:... userInfo:...];

        return child;
}


- (void)deleteChild:(MyNode *)aChild {
        NSArray *affectedChildren = [aChild selfAndAllDescendants];
                
        [[NSNotificationCenter defaultCenter] 
postNotificationName:@"NodesWillBeRemovedNotification" object:self 
userInfo:[NSDictionarydictionaryWithObjectsAndKeys:affectedChildren, @"affectedChildren", 
nil]];

        [[self mutableSetValueForKey:@"children"] removeObject:aChild];
        
        if (self.parent) {
                // Do some things that could affect some ancestor values
                ...
        }

        for (MyNode *tn in affectedChildren) {
                // Do some special processing to clean up things that might be 
pointing to the descendants
                ...
                // Set a non-persistent property on the tn node which will be 
picked up by KVO to show that the node will be removed, so we can kill 
observing etc.
                ...
                [[self managedObjectContext] deleteObject:tn];
        }
        aChild.parent = nil;

        // Do some post-processing to make sure some other values are kept in 
sync.
        ...

        // Post a notification so the front end can be updated.
        [[NSNotificationCenter defaultCenter] postNotificationName:@"NodeRemovedNotification" object:self 
userInfo:[NSDictionarydictionaryWithObjectsAndKeys:aChild, @"node", self, @"parent", 
affectedChildren, @"affectedChildren", nil]];
}


I have looked at some of the previous posts on related things, but haven't seen 
an answer that would explain what to do for this kind of thing (and some posts 
were suggesting turning off core data's undo completely and doing your own etc, 
which would not be good for me since I have a *lot* of places where it is 
working just fine for me and only about 6 places where it's not).

Thanks in advance for any advice on this.

Ken

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to