Nested undo group with CoreData

穿精又带淫゛_ 提交于 2019-12-21 01:59:16

问题


I want to add a undo manager to a coredata backed iphone application. When the user tries to add a new object (by tapping on + button) I load a new modal viewcontroller and start a new undo group in viewDidLoad.

When the user presses Cancel button, I want to rollback the changes in cancelAction callback.

Queries:

  1. Is it possible to start a nested Undo group and persist it through event loop and collate all the changes done in one single undo group? Right now, when I call beginUndoGrouping in cancelAction, I get a missing beginUndoGrouping exception.
  2. What is the significance of groupsByEvent API for NSUndoManager? Do I require to set it to NO to persist an undo group through event loop?
  3. What needs to be done in saveAction callback to make changes permanent (apart from calling save on mangedObjectContext)? How do I tell Undo Manager to stop tracking the changes?

Error Message:

* Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '_endUndoGroupRemovingIfEmpty:: NSUndoManager 0x75415f0 is in invalid state, endUndoGrouping called with no matching begin

Sample Code:

// RootViewController.m
- (void) addAction {
   // Load Modal View Controller to add new object

}

// AddViewController.m
- (void) viewDidLoad {
   // Start nested undo group
   [self.managedObjectContext processPendingChanges];
   [self.managedObjectContext.undoManager beginUndoGrouping];

   [self createModel];

}

- (void) cancelAction {
    // Revert all changes
    [self.managedObjectContext processPendingChanges];
    [self.managedObjectContext.undoManager endUndoGrouping];

    [self.managedObjectContext.undoManager undoNestedGroup];

    ...
}

- (void) saveAction {

    // Save changes
}

回答1:


Beginning with your specific questions - Yes, you can manually define the bounds of an undo operation using beginUndoGrouping and endUndoGrouping.

In this case, the undo operation should work whether or not groupsByEvent is set. This is because all the undo groups that are generated by the event loop are nested under your main open undo grouping started with beginUndoGrouping, and as long as you call undoNestedGroup directly after you call endUndoGrouping, it should work. If you are not using the event loop undo groupings, don't worry about it and set it to NO.

To make your changes permanent, close the undo group with endUndoGrouping and call save on your context. The processPendingChanges calls are not needed, and may cause issues in nested groups. If you want clear the undo operations, call removeAllActions on your undomanager after endUndoGrouping - this guarantees the changes will never be un-did.

Use breakpoints/nslog to make sure your begin/end calls are one for one.

If you want your cancel action to be like an 'undo button', you'll have to do the following:

  • Move beginUndoGrouping to viewWillAppear

  • Call endUndoGrouping in viewWillDisappear

  • re-open undo grouping at the end of your cancel action

  • re-open undo grouping at the end of your save action

Otherwise, if you leave it as is, make sure you close the dialog in your save and cancel actions, to avoid possibility of endUndoGrouping being called multiple times.

If you have any questions, please comment and I'll update.

Good luck!



来源:https://stackoverflow.com/questions/4853475/nested-undo-group-with-coredata

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!