I've got a CoreData document based application, and I'm trying to undo
my object creation in a single step.

Here's the issue - I'm storing an ordered index on my entities so I
can keep track of the order of creation. To do this, upon object
creation, I yank out the highest order parameter for my entity, add 1
to it, and use it to set up my ordered column. But the issue is, in
order to do this and make it work well, I have to put the code to
create the ordered column in a separate selector that I hit using
performSelector:, as such:

-(void) awakeFromInsert {
  [super awakeFromInsert];
  [self performSelector:@selector(createOrder:) withObject:nil afterDelay:0];
}

-(void) createOrder {
  int highOrderIndex = [self getHighestIndexSomeHow];
  [self setValue:[NSNumber numberWithInt:highOrderIndex] forKey:@"ordered"];
}

If I were to just directly call [self createOrder]; in
-awakeFromInsert, I'd end up with a duplicate entry in my
NSArrayController (though not in the context). AFAIU, that's because I
can't go out and perform queries in CoreData during awakeFromInsert,
and this is the acceptable workaround.

But the problem is, if the user undoes the creation of a new object,
two undos are required. The first one will bump the ordered parameter
back down to zero, and then the second one will actually drop the
object. It's fairly confusing since the ordered parameter isn't
displayed to the user, so it appears that the undo does nothing the
first time, but then works the second.

Even worse - potentially they could hit undo once and end up with an
object in a quasi-state with an invalid order parameter.


How can I deal with this? I've been trying various combinations of
begin/endUndoGrouping, and even turning on and off groupsByEvent, but
I haven't hit the magic incantation yet.

I also tried popping all references to the newly created object off
the stack and using prepareWithInvocationTarget: with a method that
just drops the object:

...
//at the end of createOrder up above
[undoManager removeAllActionsWithTarget:self];
[[undoManager prepareInvocationWithTarget:self] negateCreation];
}

-(void) negateCreation {
  [[self managedObjectContext] deleteObject:self];
}

That gets me closer - it actually does drop the object immediately
upon undo, but I still have an additional undo state on the stack.
That is, I can hit undo once and delete my object entirely, but then I
can hit undo a second time, and seemingly nothing happens. At that
point, I can hit redo twice, and two additional objects will appear.
One with a valid order, and one without. I'm not sure if this approach
is a dead-end or not.

Can anyone point me in the right direction?

-Jim....
_______________________________________________

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