Ios NSUndoManager调用不再存在的方法

Ios NSUndoManager调用不再存在的方法,ios,objective-c,nsundomanager,Ios,Objective C,Nsundomanager,我有一个复杂的情况,我有一个视图控制器和几个子视图控制器 情况A:当我更改子视图控制器时,我会在NSUndoManager中记录更改,并且撤销会调用子视图控制器中的撤销方法并正常工作 -(void)setElementTransform:(NSString *)transform { NSUndoManager *undoManager = [Global sharedGlobalInstance].undoMgr; [undoManager registerUndoWithTa

我有一个复杂的情况,我有一个视图控制器和几个子视图控制器

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

-(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:这有点复杂-当我移除子视图控制器时,我会在NSUndoManager中记录撤消方法(在主视图控制器中)。当我撤消该删除操作时,NSUndoManager在主视图控制器中调用undo方法,该方法将重新创建子视图控制器。那也行

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

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


我还可以如何处理此问题?

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


如果您只需要从撤消堆栈中获取针对死掉的子视图控制器的操作,请在子视图控制器的dealloc(或viewwilldiscover,或viewDidUnload,视情况而定)方法中调用removeAllActionsWithTarget:self。谢谢-removeAllActionsWithTarget:self是停止崩溃的关键,但它有效地将该对象从撤消树中删除。我将在将来在自定义撤消管理器中实现您的其他建议。