NSUndoManager:在一个运行循环周期中分隔多个更改 [英] NSUndoManager : separate multiple changes in one run loop cycle

查看:225
本文介绍了NSUndoManager:在一个运行循环周期中分隔多个更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用[undoManager registerUndoWithTarget ::]来添加一些更改以撤消堆栈。
然而,有时发生,当在一个运行循环周期中两个更改添加到同一组,因此它们立即还原,这不是我想要的行为。
我想分离这两个更改在撤消堆栈中有两个项目。
如何正确实现这个?使用[NSObject performSelector:]在下一个运行循环循环中调用第二个undo添加?



谢谢。

NSUndoManager 会在一个运行循环周期中自动对撤销操作进行分组。您可以更改该行为,但: - [NSUndoManager setGroupsByEvent:] 将禁用自动分组,如果您发送 NO 。请注意,您需要确保所有组在undo管理器执行 -undo -undoNestedGroup 之前关闭。由于其他Cocoa类可能希望在不显式创建组的情况下注册撤销操作,因此您可以在注册撤消组之前禁用自动分组,在注册这些组之后重新启用。



例如:

   - (void)someMethod {
NSUndoManager * undoManager = ...; //例如,[[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 是另一个撤消组的一部分。两个组都包含在一个块中,其中undo管理器不将当前运行循环周期的默认撤销组中的所有操作分组。执行此方法后,第一个撤消操作撤销 string2 string3 更改和后续撤销操作撤消应用的更改

我使用了C块<$ c $



NB:

NSUndoManager 线程安全。


I'm using [undoManager registerUndoWithTarget::] to add some changes to undo stack. However, sometimes happens, when in one run loop cycle two changes added to the same group, so they are reverted at once, which is not behavior I'd like to have. I want to separate these two changes to have two items in undo stack. How to correctly implement this? Use [NSObject performSelector: ] to call second undo addition in the next run loop cycle, or whatever else?

Thanks.

解决方案

As you’ve noticed, by default NSUndoManager automatically groups undo operations in one run loop cycle. You can change that behaviour, though: -[NSUndoManager setGroupsByEvent:] will disable automatic grouping if you send a NO argument. Note that you need to make sure that all groups are closed before the undo manager executes -undo or -undoNestedGroup. Since other Cocoa classes may want to register undo operations without explicitly creating a group, you can disable automatic grouping right before you register undo groups, reenabling after you’ve registered those groups.

For example:

- (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];
}

In -someMethod, three changes are applied to modelObject, modifying its string1, string2 and string3 properties. The change applied to string1 is part of an undo group and the changes to string2 and string3 are part of another undo group. Both groups are enclosed in a block where the undo manager isn’t grouping all operations in the default undo group for the current run loop cycle. After this method is executed, the first undo operation undoes both string2 and string3 changes and subsequent undo operation undoes the change applied to string1, provided there wasn’t another undo group enclosing them.

I used C blocks {} to make these two hierarchies (no grouping by events and undo groups) clear.

NB: NSUndoManager is not thread-safe.

这篇关于NSUndoManager:在一个运行循环周期中分隔多个更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆