为什么按 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 控制器引发的。如果我保留它,它就不会崩溃。
一些进一步的信息:
- 该面板包含(仅)一个 WebView。
- 面板的关闭时释放复选框已关闭。
- 所有其他选项均为默认选项(停用时隐藏除外。)
我找不到调试器的问题,因为崩溃发生在 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 通过按键来完成它的事情。
我的应用程序中有一个 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 控制器引发的。如果我保留它,它就不会崩溃。
一些进一步的信息:
- 该面板包含(仅)一个 WebView。
- 面板的关闭时释放复选框已关闭。
- 所有其他选项均为默认选项(停用时隐藏除外。)
我找不到调试器的问题,因为崩溃发生在 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 通过按键来完成它的事情。