带有核心数据的 NSUndoManager - 重做不起作用

发布于 2024-08-25 00:48:05 字数 757 浏览 5 评论 0原文

我有一个基于 Core Data 文档的应用程序,它支持通过与 NSManagedObjectContext 关联的内置 NSUndoManager 进行撤消/重做。我设置了一些操作,这些操作在 Core Data 中执行大量任务,通过 beginUndoGrouping/endUndoGrouping 将所有这些任务包装到撤消组中,并由 NSUndoManager 处理。

撤消效果很好。我可以执行多个连续的操作,然后依次撤消其中的每一个操作,并且我的应用程序的状态得到正确维护。但是,“重做”菜单项永远不会启用。这意味着 NSUndoManager 告诉菜单没有可以重做的项目。

我想知道为什么 NSUndoManager 似乎在撤消项目后就忘记了这些项目,并且不允许重做发生?

我应该提到的一件事是,我在打开/创建文档后禁用撤消注册。当我执行操作时,我调用 enableUndoRegistrationbeginUndoGrouping,执行该操作,然后调用 processPendingChangessetActionName:endUndoGrouping,最后是disableUndoRegistration。这确保只有特定的操作是可撤消的,并且我在这些操作之外所做的任何其他数据更改都不会被 NSUndoManager 注意到。这可能是问题的一部分,但如果是这样,我想知道为什么它会影响重做?

提前致谢。

I have a Core Data document-based app which support undo/redo via the built-in NSUndoManager associated with the NSManagedObjectContext. I have a few actions set up which perform numerous tasks within Core Data, wrap all these tasks into an undo group via beginUndoGrouping/endUndoGrouping, and are processed by the NSUndoManager.

Undo works fine. I can perform several successive actions, and each then undo each one of them successively and my app's state is maintained correctly. However, the "Redo" menu item is never enabled. This means that the NSUndoManager is telling the menu that there are no items to redo.

I am wondering why the NSUndoManager is seemingly forgetting about items once they are undone, and not allowing redos to occur?

One thing I should mention is that I'm disabling undo registration after a document is opened/created. When I perform an action, I call enableUndoRegistration, beginUndoGrouping, perform the action, then call processPendingChanges, setActionName:, endUndoGrouping, and finally disableUndoRegistration. This makes sure that only specific actions are undoable, and any other data changes I make outside of these go unnoticed to the NSUndoManager. This may be a part of the issue, but if so I'm wondering why it's affecting redo?

Thanks in advance.

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

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

发布评论

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

评论(3

面如桃花 2024-09-01 00:48:05

实际上,只要你在-undo和-re​​do之前调用enableUndoRegistration(并在它们之后调用disableUndoRegistration),你就可以达到你想要的效果。

我相信您只是在更改托管对象之前和之后调用了enable(/disable)UndoRegistration。这意味着您的“撤消”未在撤消管理器中注册,因此您无法“重做”它。

Actually, as long as you call enableUndoRegistration before both -undo and -redo (and disableUndoRegistration after them), you can achieve what you were after.

I believe that you were only calling enable(/disable)UndoRegistration before and after the changes to your managed objects. This means that your 'undo' was not registered with the undo manager, and hence you could not 'redo' it.

榕城若虚 2024-09-01 00:48:05

我已经通过以下方式解决了这个问题:

始终保持启用撤消注册,除了我明确不想记录撤消的时候。

我了解到:

如果您在执行要记录的更改之前启用撤消注册,并在提交这些更改后立即禁用,则 NSUndoManager 的重做堆栈永远不会被填充。

因此,切勿调用 disableUndoRegistration

I have fixed this issue by:

Keeping undo registration enabled all the time, except for the times when I explicitly do not want to record undos.

I have learned that:

If you enable undo registration just before performing changes that you want to record, and disable immediately after committing those changes, the NSUndoManager's redo stack never gets populated.

So, never call disableUndoRegistration.

暮色兮凉城 2024-09-01 00:48:05

我在保持“重做”启用的同时调用了disableUndoManager。为此,我对 NSUndoManager 进行了子类化并包含此方法:

-(void) undo
{
  [[appDelegate managedObjectContext] processPendingChanges];
  [self enableUndoRegistration];
  [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]];
  [super undo];
  [[appDelegate managedObjectContext] processPendingChanges];
  [self disableUndoRegistration];
}

正如 Stefanf 在 NSUndoManager、核心数据和选择性撤消/重做:“NSUndoManager 等待下一个运行循环周期,直到注册您的更改”

I called disableUndoManager while keeping "Redo" enabled. To do this I subclassed NSUndoManager and included this method:

-(void) undo
{
  [[appDelegate managedObjectContext] processPendingChanges];
  [self enableUndoRegistration];
  [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]];
  [super undo];
  [[appDelegate managedObjectContext] processPendingChanges];
  [self disableUndoRegistration];
}

As stated by Stefanf in NSUndoManager, Core Data and selective undo/redo: "NSUndoManager waits for the next run loop cycle until it registers your changes"

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