使用 CoreData 嵌套撤消组

发布于 2024-10-15 13:39:09 字数 1298 浏览 4 评论 0原文

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

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

查询:

  1. 是否可以启动一个嵌套的撤消组并通过事件循环保留它并整理在一个撤消组中完成的所有更改?现在,当我在 cancelAction 中调用 beginUndoGrouping 时,我收到丢失的 beginUndoGrouping 异常。
  2. groupsByEvent API 对于 NSUndoManager 有什么意义?我是否需要将其设置为“否”才能通过事件循环保留撤消组?
  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
}

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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦过后 2024-10-22 13:39:09

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

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

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

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

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

  • 将 beginUndoGrouping 移动到 viewWillAppear

  • 在 viewWillDisappear 中调用 endUndoGrouping

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

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

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

如果有任何疑问,请评论,我会更新。

祝你好运!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文