【发布时间】:2022-01-24 18:28:53
【问题描述】:
我正在使用 XCode Swift,使用带有 Storyboard 的 Cocoa,我需要能够以编程方式创建和关闭自己的窗口。
为了尽可能简单地重复这个问题,我从一个空的故事板项目开始,只更改 ViewController.swift 中的 viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
let rect = NSRect( x:500, y:500, width:800, height:500 )
let mask = NSWindow.StyleMask( arrayLiteral: .closable, .miniaturizable, .resizable, .titled )
let win = NSWindow( contentRect: rect, styleMask: mask, backing: .buffered, defer: false )
win.orderFront( win )
}
应用程序运行,并打开两个窗口。较小的来自故事板,可以毫无问题地关闭,但是当我关闭我创建的较大窗口时,应用程序在 appDelegate 中崩溃
线程 1:EXC_BAD_ACCESS(代码=1,地址=0x20)
我假设我在这里做了一些愚蠢的事情 - 我错过了什么?
我发现如果我设置了
win.isReleasedWhenClosed = false
问题消失了,但是我认为内存没有被释放。
我还发现,如果我在关闭数组之前将窗口句柄附加到数组,问题也会消失:
private var broken_windows [NSWindow] = []
public func windowShouldClose( _ sender: NSWindow ) -> Bool {
broken_windows.append( sender )
return true
}
然而这个数组在某种程度上是完全不可触碰的,并且在窗口关闭后任何试图访问它的成员都会导致应用程序崩溃。
【问题讨论】:
-
崩溃发生在应用程序委托的哪个位置?您尚未显示您的应用委托代码。
-
我没有应用程序委托代码,这是一个空项目,如上所述,仅由我在问题中发布的代码修改。我希望我必须在应用程序委托中实现一些东西才能正确关闭窗口,我不知道在这里放什么代码 - 这是我的问题。
-
当我说“我没有应用程序委托代码”时,我的意思是我在启动项目时没有修改 Xcode IDE 提供的默认模板。我会在这里发布,但我认为在评论中不合适。我并不是说没有应用程序委托。当应用程序崩溃时,lldb 指向
class AppDelegate: NSObject, NSApplicationDelegate {声明,并给我一个我无法遵循的堆栈跟踪。