Reputation: 469
Does CoreData control the order in which events are executed within a given undo grouping?
Simplified, I have code like this, where context is an NSManagedObjectContext:
[[[context undoManager] prepareWithInvocationTarget:self] a];
MyManagedObject *newMO = [NSEntityDescription insertNewObjectForEntityForName:@"MyManagedObject" inManagedObjectContext:context];
[[[context undoManager] prepareWithInvocationTarget:self] b];
If I print the undo stack, it looks like this:
0: endUndoGrouping
1: target: NSManagedObjectContext 0x146a89f0 -- selector:_undoInsertions: -- arg:__NSArrayI 0x145bd590
2: target: ViewController 0x146a5470 -- selector:b
3: target: NSManagedObjectContext 0x146a89f0 -- selector:_noop: -- arg:__NSArrayI 0x14638cb0
4: target: ViewController 0x146a5470 -- selector:a
5: beginUndoGrouping
It seems odd that the noop would be inserted between my two custom undo calls, and then the undoInsertions would be placed after that on stack. Can anyone explain how this works?
Upvotes: 0
Views: 166
Reputation: 1931
From the docs (emphasis added)
You also can use other standard undo manager functionality, such grouping undo events. Core Data, though, queues up the undo registrations and adds them in a batch (this allows the framework to coalesce changes, negate contradictory changes, and perform various other operations that work better with hindsight than immediacy). If you use methods other than beginUndoGrouping and endUndoGrouping, to ensure that any queued operations are properly flushed you must first therefore send the managed object context a processPendingChanges message.
Under the hood the undo
operation is doing some internal optimizing, according to an algorithm that you have no explicit insight into.
If exact reversal of order is something you absolutely require, you will probably have to roll your own queue of operations, and manually revert each one in FILO (first in, last out) order.
Upvotes: 1