macOS:调用addWindowController后WindowController的document属性未设置
你的场景是在Document类的makeWindowControllers方法中添加自定义WindowController,但调用addWindowController后,该WindowController的document属性未被自动赋值,结合你提供的代码,主要有以下几个可能的原因:
1. 窗口被立即关闭打断了关联流程
你在调用addWindowController后立刻执行了movieWindowController.window?.performClose(self),这会触发窗口的关闭流程,而Document给WindowController设置document属性的操作可能还未完成。
AppKit中,addWindowController只是将WindowController加入管理队列,内部的关联(包括设置document属性)可能是异步或延迟执行的。此时立即关闭窗口,会导致WindowController提前进入销毁/清理状态,系统会跳过document属性的赋值逻辑。
2. WindowController实例化失败
代码中使用as? NSWindowController进行类型转换,如果故事板中指定的控制器类型不匹配,movieWindowController会是nil。这种情况下addWindowController实际没有生效,自然不会有document属性赋值。可以添加断言确认实例化是否成功:
guard let movieWindowController = movieStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("MovieWindowController")) as? NSWindowController else { fatalError("Failed to instantiate MovieWindowController from storyboard") } self.addWindowController(movieWindowController)
3. 故事板中WindowController的配置问题
如果故事板里的WindowController被设置为独立的顶级控制器(没有正确关联到Document的生命周期),或者窗口的shouldClose代理提前阻止了关联流程,也可能导致document属性无法被赋值。检查故事板中WindowController的属性,确保它是作为Document的子控制器被设计的。
解决方案
- 移除立即关闭窗口的代码,或者延迟执行关闭操作,给系统足够时间完成
document属性的赋值:self.addWindowController(movieWindowController) // 延迟执行关闭,确保关联完成 DispatchQueue.main.async { movieWindowController.window?.performClose(self) } - 确认WindowController实例化成功,避免nil值传入
addWindowController - 检查故事板中WindowController的配置,确保其符合Document子控制器的设计规范
内容的提问来源于stack exchange,提问作者blackirishman

