0

我的应用程序中有一个 NSPanel,main()只要按 Escape 键关闭它,它就会使应用程序崩溃(EXC_BAD_ACCESS in )。以任何其他方式关闭它(文件>关闭,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 年 2 月 19 日更新:

启用僵尸让我得到了消息-[NSWindowController setNextResponder:]: message sent to deallocated instance 0x60000028a9b0。因此,在窗口控制器发布后,某些东西正在与窗口控制器对话。因为那不是我的直接代码(我什至没有继承 NSWindowController,也没有在任何地方对窗口控制器进行任何调用),所以问题仍然存在:与其他方法相比,通过点击 Escape 关闭窗口有什么不同(像 Cmd-W)?

2018 年 2 月 19 日更新 #2:

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

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

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

4

1 回答 1

-1

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

这允许 WebView 用按键来做它的事情。

于 2018-02-22T10:58:31.210 回答