为什么在通过按Escape关闭NSPanel时我的应用程序崩溃了?

时间:2018-02-16 11:34:19

标签: objective-c crash nspanel

我的应用中有一个NSPanel,只要按下Escape键,它就会崩溃应用程序(main()中的EXC_BAD_ACCESS)。以任何其他方式关闭它(文件>关闭,Cmd-W,单击红色关闭按钮)工作正常。

通过从故事板中实例化其窗口控制器来显示该面板。对窗口控制器的引用存储在字典中。在视图控制器-viewWillDisappear中,窗口控制器将从字典中删除。

    wc = [[NSStoryboard storyboardWithName:@"Main" bundle:nil] instantiateControllerWithIdentifier:kSBIDPreviewWindowController];
    // ...
    [windowsOfType addObject:wc];
    // ...
    [wc showWindow:self];

关闭:

-(void)viewDidDisappear {
    // ...
    if ([windowsOfType containsObject:winController]) {
        [windowsOfType removeObject:winController];
    }
}

显然是通过从字典中删除窗口控制器来触发崩溃。如果我保留它,它就不会崩溃。

进一步的信息:

  • 该面板包含(仅)WebView。
  • 面板的关闭时释放复选框关闭。
  • 所有其他选项均为默认选项(取消激活隐藏除外)。

我无法找到调试器的问题,因为崩溃发生在main()中,即。窗户关闭后。

知道可能导致这种情况的原因吗?

而且,更一般地说,我应该使用哪种技术来调试这种情况?

更新2018-02-19:

启用Zombies给我的消息-[NSWindowController setNextResponder:]: message sent to deallocated instance 0x60000028a9b0。因此,在窗口控制器发布后,它正在与窗口控制器通信。由于这不是我的代码直接(我甚至没有对NSWindowController进行子类化,也没有在任何地方调用窗口控制器),问题仍然存在:当窗口通过击中Escape关闭时有什么不同其他方法(如Cmd-W)?

更新2018-02-19#2:

仪器给出了一个有趣的结果。显然我在面板上的WebView尝试在面板关闭/解除分配后处理按下Escape键(在我的情况下由视图控制器触发-viewDidDisappear }。)

Zombie来源为-[WebResponderChainSink detach]-[WebHTMLView keyDown:]称为(通过一些中间调用)。

看起来WebView没有正确传递按键或其他东西......?这是否意味着面板上的WebView是一个坏主意?

1 个答案:

答案 0 :(得分:0)

我找到了避免此类崩溃的解决方案;您必须延迟释放对窗口控制器的最后一个引用,直到当前事件处理完成后(例如,使用dispatch_async()。)

这允许WebView使用按键执行操作。