macOS下Swift关闭窗口后重开触发EXC_BAD_ACCESS错误求助
问题原因与解决方案
问题根源
你遇到的EXC_BAD_ACCESS错误,核心原因是无效内存访问:
- 代码中设置了
window.isReleasedWhenClosed = true,关闭窗口时系统会直接销毁NSWindow实例并释放其内存。 - 你的
window变量是隐式解包可选类型(NSWindow!),实例被释放后,变量并未自动置为nil,而是变成指向无效内存的野指针。 - 再次调用
openWindow()时,if window == nil判断会错误返回false(指针地址仍存在,但指向的内存已失效),执行window.makeKeyAndOrderFront(self)时,尝试访问已释放对象的方法,触发内存访问错误。
解决办法
方案一:关闭窗口时不释放实例(适合简单场景)
将window.isReleasedWhenClosed = true修改为:
window.isReleasedWhenClosed = false
关闭窗口时,NSWindow实例会被保留仅隐藏,再次调用openWindow()时直接将窗口前置即可,无内存问题。
方案二:保持释放机制,同步清空变量
若必须在关闭窗口时释放实例,可通过监听窗口关闭通知,在实例释放前将window变量置为nil:
- 创建
window后添加通知监听:
window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 550, height: 300), styleMask: [.miniaturizable, .closable, .titled], backing: .buffered, defer: false) // 添加监听代码 NotificationCenter.default.addObserver(self, selector: #selector(windowWillClose(_:)), name: NSWindow.willCloseNotification, object: window)
- 实现通知响应方法:
@objc private func windowWillClose(_ notification: Notification) { window = nil }
- 在对象销毁时移除观察者(避免内存泄漏):
deinit { NotificationCenter.default.removeObserver(self) }
关闭窗口后window变量会被置为nil,再次调用openWindow()时会重新创建窗口实例,避免访问无效内存。
内容的提问来源于stack exchange,提问作者AppleDeveloper
相关产品推荐
相关产品推荐

