我试图在块代码中添加一些撤消/重做(从NSOpenPanel导入一些文件),只要代码来自块,主代码就可以工作,但NSUndoManager代码不会保存,也不会出现任何错误。 NSUndoManager代码可以在其他任何地方工作,只要它不在块
中示例NSUndoManager代码如下:
// Undo Work
id undoObject = [NSApp targetForAction:@selector(undoManager) to:nil from:self];
NSUndoManager *undoManager = [undoObject undoManager];
[[undoManager prepareWithInvocationTarget:self] deleteImages];
[undoManager setActionName:@"import images"];
以下显示代码执行和不执行的位置:
/* NSUndoManager code works */
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel beginSheetModalForWindow:[self.windowController window]
completionHandler:^(NSInteger result) {
if (result == NSFileHandlingPanelOKButton) {
/* NSUndoManager code does not work,
it also does not work inside importImages: */
[self importImages:[openPanel URLs]];
} else {
[openPanel close];
}
}];
/* NSUndoManager code works */
答案 0 :(得分:0)
该块在堆栈上,因此当调用撤消操作时,撤销管理器对象可能已经被释放(或者如果不是这样,则设置为nil)。因此,确保撤消管理器将处于活动状态,声明是作为类实例,还是使用__block语法(没有ARC):
__block NSUndoManager* undoManager;
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel beginSheetModalForWindow:[self.windowController window]
completionHandler:^(NSInteger result) {
if (result == NSFileHandlingPanelOKButton) {
id undoObject = [NSApp targetForAction:@selector(undoManager) to:nil from:self];
undoManager=[undoObject undoManager];
[[undoManager prepareWithInvocationTarget:self] deleteImages];
[undoManager setActionName:@"import images"];
[self importImages:[openPanel URLs]];
} else {
[openPanel close];
}
}];
完成撤消管理器后,您可以将其设置为nil。