NSUndoManager调用方法不再存在

问题描述:

我有一个复杂的情况,我有一个视图控制器和几个子视图控制器。NSUndoManager调用方法不再存在

情况A:当我更改子视图控制器时,我将更改记录在NSUndoManager中,undo调用子视图控制器中的undo方法,并且工作正常。

-(void)setElementTransform:(NSString *)transform 
{ 
    NSUndoManager *undoManager = [Global sharedGlobalInstance].undoMgr; 
    [undoManager registerUndoWithTarget:self selector:@selector(setElementTransform:) object:self.element.transform]; 
    self.element.transform = transform; 
    self.view.transform = CGAffineTransformFromString(transform); 
} 

情况B:这有点更复杂的 - 当我除去副视图控制器,I记录NSUndoManager撤消方法(在主视图控制器)。当我撤销删除时,NSUndoManager将在主视图控制器中调用undo方法,该方法会重新创建子视图控制器。这也很好。

问题是,如果我做情况A,然后情况B,我有两个在撤消堆栈。我可以撤消情境B,但情境A在子视图控制器中引用了一个不再存在的撤消方法(它在情形B中通过删除和撤消被删除并重新创建)。

我不认为有任何更新NSUndoManager的方法,以便我可以更改引用旧的子视图控制器?

我还能如何处理这个问题?

您可以使用不会丢弃的对象注册所有撤消操作。例如在顶层视图控制器,甚至应用程序委托或单独的单例。然后,您需要在registerUndoWithTarget的object参数中包含:selector:object:足够的信息,用于在相应的子视图控制器或其替换上应用撤消操作。

如果您只需要针对死堆子视图控制器执行针对撤消堆栈的操作,请在子视图控制器的dealloc(或viewWillDisappear或viewDidUnload,适当时)方法中调用removeAllActionsWithTarget:self。

+0

谢谢 - removeAllActionsWithTarget:self是停止崩溃的关键,但它可以有效地从undo树中移除该对象。我将在未来的某个时刻在自定义撤消管理器中实施您的其他建议。 – Caroline 2013-03-19 05:39:15