gpt4 book ai didi

objective-c - Core Data UndoManager 发送奇怪的 NS

转载 作者:搜寻专家 更新时间:2023-10-30 19:49:34 25 4
gpt4 key购买 nike

我正在开发的应用程序允许用户管理一些 Assets 。用户可以在屏幕上四处创建/删除/编辑/拆分/移动 Assets 。用户需要能够撤消所有这些步骤。

Assets 由核心数据管理(是的,undoManager 已实例化)。

对于这些操作中的每一个,我都使用这对创建撤消分组:

beginUndoGrouping ... endUndoGrouping

Here's a simple example (sequence 1):
// SPLIT
- (void) menuSplitPiece: (id) sender
{
[self.managedObjectContext.undoManager beginUndoGrouping];
[self.managedObjectContext.undoManager setActionName:@"Split"];
//... do the split
[self.managedObjectContext.undoManager endUndoGrouping];
// if the user cancels the split action, call [self.managedObjectContext.undoManager undo] here;
}

我对编辑做同样的事情:如果用户取消编辑,那么我在 endUndoGrouping 之后立即调用撤消。

除了一个异常(exception),一切都很顺利:除了我创建的组之外,还有其他由我无法控制的 Core Data 创建的组。这就是我的意思:

我像这样注册接收 NSUndoManagerDidCloseUndoGroupNotification 通知:

- (void) registerUndoListener
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didCloseUndoGroup:)
name:NSUndoManagerDidCloseUndoGroupNotification object:nil];
...}

我使用这些通知来刷新撤消按钮并显示由于某些操作而被撤消的操作的名称:例如撤消拆分

然而,didCloseUndoGroup 为上述每个操作调用/通知两次(例如,第 1 部分,在 endUndoGrouping 之后):

在第一次通知时,self.managedObjectContext.undoManager.undoActionName 包含我设置的撤消操作名称,这是我预期的,而第二次 undoActionName 是一个空字符串。

作为一种解决方法,我尝试简单地撤消具有空名称的操作(假设它们不是我的并且我不需要它们),然后看看我是否遗漏了什么。

现在,didCloseUndoGroup 看起来像这样

- (void) didCloseUndoGroup: (NSNotification *) notification
{
...
if ([self.managedObjectContext.undoManager.undoActionName isEqualToString:@""]){
[self.managedObjectContext.undoManager undo];
}
[self refreshUndoButton]; // this method displays the name of the undo action on the button
...
}

它神奇地起作用了,我可以使用“撤消”撤消任何命令、任意数量的层。但这不是它应该的工作方式......

我之前尝试过的其他一些事情:

  1. [self.managedObjectContext processPendingChanges] 在打开任何分组之前。它仍在发送两个通知。
  2. 我尝试的另一件事是 disableUndoRegistration/enableUndoRegistration。这一个产生了一个异常:“无效状态,调用了太多嵌套撤消组的撤消”

以上都没有帮助我“隔离”我之前提到的神秘分组。

我不应该收到两次 NSUndoManagerDidCloseUndoGroupNotification 通知。或者,我应该吗?有没有更好的方法来处理这种情况?

更新这就是最终奏效的方法。以前我一收到通知就自动撤消无名组。这就是导致问题的原因。现在,我撤消所有操作,直到到达我的目标组,然后为该组执行最后一次撤消。

“undoManagerHelper”只是一个堆栈管理系统,它为每个压入堆栈的命令生成唯一的 ID。我使用这个唯一 ID 来命名该组。

- (BOOL) undoLastAction
{
NSString *lastActionID = [self.undoManagerHelper pop]; // the command I'm looking for
if (lastActionID == nil) return false;

//... undo until there is nothing to undo or self.managedObjectContext.undoManager.undoActionName equals lastActionID

//the actual undo here
if ([currentActionID isEqualToString: lastActionID] && [self.managedObjectContext.undoManager canUndo]){
[self.managedObjectContext.undoManager undo];
}
return true;
}

- (void) beginUndoGroupingWithName: (NSString *) name
{

[self.managedObjectContext processPendingChanges];
[self.managedObjectContext.undoManager beginUndoGrouping];
NSString *actionID = [self.undoManagerHelper push: name];
[self.managedObjectContext.undoManager setActionName:actionID];
}

- (void) closeLastUndoGrouping
{
[self.managedObjectContext.undoManager endUndoGrouping];
[self.managedObjectContext processPendingChanges];
}

最佳答案

根据 beginUndoGrouping 的文档 - https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSUndoManager_Class/Reference/Reference.html - “默认情况下,撤消组在事件循环开始时自动开始,但您可以使用此方法开始自己的撤消组,并将它们嵌套在其他组中。”未命名组是包含所有操作的默认撤消组,听起来您应该根据自己的情况忽略未命名组。

关于objective-c - Core Data UndoManager 发送奇怪的 NS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12677174/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com