为什么按 Escape 关闭 NSPanel 后我的应用程序会崩溃?

Why does my app crash when an NSPanel is closed by pressing Escape?

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

面板通过从情节提要中实例化其 window 控制器来显示。对 window 控制器的引用存储在字典中。在视图控制器的 -viewWillDisappear 中,window 控制器已从字典中删除。

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

关闭时:

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

崩溃显然是由从字典中删除 window 控制器引发的。如果我保留它,它就不会崩溃。

一些进一步的信息:

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

知道是什么原因造成的吗?

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

2018-02-19 更新:

启用僵尸让我收到消息 -[NSWindowController setNextResponder:]: message sent to deallocated instance 0x60000028a9b0。所以在 window 控制器被释放后,有东西在与它对话。因为那不是我的直接代码(我什至没有子类化 NSWindowController,也没有在任何地方调用 window 控制器),问题仍然存在:当 window 被关闭时有什么不同与其他方法(如 Cmd-W)相比,点击 Escape?

2018-02-19 更新 #2:

仪器给出了一个有趣的结果。显然,我在面板上的 WebView 试图在 面板 closed/deallocated 之后处理 Escape 键的按下(在我的情况下由视图控制器的 [=15 触发) =].)

Zombie 源是 -[WebResponderChainSink detach],由 -[WebHTMLView keyDown:] 调用(通过一些中间调用)。

WebView 似乎没有正确传递按键或其他东西...?这是否意味着面板上的 WebView 不是一个好主意?

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

这允许 WebView 通过按键来完成它的事情。