6

我想将撤消管理器添加到支持 coredata 的 iphone 应用程序。当用户尝试添加一个新对象时(通过点击 + 按钮),我加载一个新的模态视图控制器并在 viewDidLoad 中启动一个新的撤消组。

当用户按下取消按钮时,我想回滚取消操作回调中的更改。

查询:

  1. 是否可以启动一个嵌套的撤消组并通过事件循环将其持久化并整理在一个撤消组中完成的所有更改?现在,当我在 cancelAction 中调用 beginUndoGrouping 时,我得到一个缺少的 beginUndoGrouping 异常。
  2. groupsByEvent API 对 NSUndoManager 有什么意义?我是否需要将其设置为 NO 才能通过事件循环保留撤消组?
  3. 在 saveAction 回调中需要做什么才能使更改永久化(除了在 mangedObjectContext 上调用 save)?我如何告诉撤消管理器停止跟踪更改?

错误信息:

*由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“_endUndoGroupRemovingIfEmpty::NSUndoManager 0x75415f0 处于无效状态,调用 endUndoGrouping 时没有匹配的开始

示例代码:

// 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
}
4

1 回答 1

7

从您的具体问题开始 - 是的,您可以使用 beginUndoGrouping 和 endUndoGrouping 手动定义撤消操作的范围。

在这种情况下,无论是否设置了 groupsByEvent,撤消操作都应该起作用。这是因为事件循环生成的所有撤消组都嵌套在以 beginUndoGrouping 开头的主打开撤消分组下,只要在调用 endUndoGrouping 后直接调用 undoNestedGroup,它应该可以工作。如果您不使用事件循环撤消分组,请不要担心并将其设置为 NO。

要使您的更改永久化,请使用 endUndoGrouping 关闭撤消组并在您的上下文中调用 save。不需要 processPendingChanges 调用,这可能会导致嵌套组出现问题。如果您想清除撤消操作,请在 endUndoGrouping 之后在您的撤消管理器上调用 removeAllActions - 这可以保证更改永远不会被撤消。

使用断点/nslog 确保您的开始/结束调用是一对一的。

如果您希望取消操作像“撤消按钮”,则必须执行以下操作:

  • 移动 beginUndoGrouping 到 viewWillAppear

  • 在 viewWillDisappear 中调用 endUndoGrouping

  • 在取消操作结束时重新打开撤消分组

  • 在保存操作结束时重新打开撤消分组

否则,如果您保持原样,请确保在保存和取消操作中关闭对话框,以避免 endUndoGrouping 被多次调用的可能性。

如果您有任何问题,请发表评论,我会更新。

祝你好运!

于 2011-11-10T20:31:39.330 回答