我正在使用 [undoManager registerUndoWithTarget::] 向撤消堆栈添加一些更改。 然而,有时会发生,当在一个运行循环周期中将两个更改添加到同一组时,它们会立即恢复,这不是我想要的行为。 我想将这两个更改分开,以便在撤消堆栈中有两个项目。 如何正确实现呢?使用 [NSObject performSelector: ] 在下一个运行循环周期中调用第二个撤消添加,或者其他什么?
谢谢。
最佳答案
正如您所注意到的,默认情况下 NSUndoManager
会自动将撤消操作分组在一个运行循环周期中。不过,您可以更改该行为:如果您发送 NO
参数,-[NSUndoManager setGroupsByEvent:]
将禁用自动分组。请注意,您需要确保在撤消管理器执行 -undo
或 -undoNestedGroup
之前关闭所有组。由于其他 Cocoa 类可能希望在不显式创建组的情况下注册撤消操作,因此您可以在注册撤消组之前禁用自动分组,在注册这些组后重新启用。
例如:
- (void)someMethod {
NSUndoManager *undoManager = …; // for example, [[self window] undoManager]
[undoManager setGroupsByEvent:NO];
{
[undoManager beginUndoGrouping];
{
[undoManager registerUndoWithTarget:modelObject selector:@selector(setString1:) object:[modelObject string1]];
[modelObject setStringValue:newValue1];
[undoManager setActionName:@"String 1 Change"];
}
[undoManager endUndoGrouping];
[undoManager beginUndoGrouping];
{
[undoManager registerUndoWithTarget:modelObject selector:@selector(setString2:) object:[modelObject string2]];
[modelObject setString2:newValue3];
[undoManager registerUndoWithTarget:modelObject selector:@selector(setString3:) object:[modelObject string3]];
[modelObject setString3:newValue3];
[undoManager setActionName:@"Strings 2 and 3 Change"];
}
[undoManager endUndoGrouping];
}
[undoManager setGroupsByEvent:YES];
}
在-someMethod
中,对modelObject
应用了三个变化,修改了它的string1
、string2
和string3
属性。应用于 string1
的更改是撤消组的一部分,对 string2
和 string3
的更改是另一个撤消组的一部分。这两个组都包含在一个 block 中,其中撤消管理器不会将当前运行循环周期的默认撤消组中的所有操作分组。执行此方法后,第一个撤消操作撤消 string2
和 string3
更改,随后的撤消操作撤消应用于 string1
的更改,前提是不是另一个包含它们的撤消组。
我使用 C block {}
来使这两个层次结构(没有按事件分组和撤消组)变得清晰。
注意:NSUndoManager
不是线程安全的。
关于objective-c - NSUndoManager : separate multiple changes in one run loop cycle,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16763716/