我使用 Xcode 模板编写了一个带有 Storyboard的 macOS 文档类型应用程序,并且沿线的某处初始应用程序启动和文档之间的关联与预期模式不同,因此没有 NSDocument 初始化程序我希望在应用程序首次启动时被调用(但此后每个新窗口都会被调用)。
我已经将所有四个记录在案的 NSDocument 初始化程序子类化,如下所示:
public class Simulation: NSDocument {
override init() {
debugPrint("--------------------\(#file)->\(#function) called")
super.init()
}
init(contentsOf: URL, ofType: String) throws {
debugPrint("--------------------\(#file)->\(#function) called")
fatalError()
}
init(for: URL?, withContentsOf: URL, ofType: String) throws {
debugPrint("--------------------\(#file)->\(#function) called")
fatalError()
}
convenience init(type: String) throws {
debugPrint("--------------------\(#file)->\(#function) called, type: \(type)")
self.init()
}
public override class func autosavesInPlace() -> Bool {
debugPrint("--------------------\(#file)->\(#function) called")
return false
}
}
当应用程序启动时,所有 init 都不会显示 debugPrint 输出。应用程序窗口在启动时成功创建,没有明显文档关联。
但是,我注意到一些我无法解释的非常奇怪的行为:
- 虽然我没有看到任何 init 调用,但在应用程序在文档的某个实例上启动后,autosavesInPlace 被调用了三次
- 当我使用 cmd-N(即 File->New,因此是 newDocument())创建一个新文档时,autosavesInPlace 又被调用了三次,然后执行了文档初始化!
- 我从未见过对 makeWindowControllers() 的调用
我的 NSDocument 子类名为 Simulation。异常似乎是在绕过 Simulation.init 的初始启动中有一些魔法,但此后每次创建文档+窗口时都调用它。
这是我的问题:
- 为什么初始启动不调用 Simulation.init()?
- 当只有初始的、看似部分构建的窗口时,autosavesInPlace 如何找到要调用的 Simulation 实例?
最佳答案
在你的 Storyboard中,确保你的 Window Controller 和它的 Content View Controller 都没有选中 Is Initial Controller
并且 Presentation
设置为 Multiple
属性检查器。
选中 Is Initial Controller
将导致应用程序在任何 NSDocument
/NSDocumentController
“魔术”发生之前实例化一个窗口 Controller 。 Presentation: Multiple
应该选择连贯性,尽管它可能不会真正产生影响。
此外,请确保您的文档类型在 Info.plist
中正确设置,尤其是 NSDocumentClass
键(应包含 $(PRODUCT_MODULE_NAME).Simulation
).
我相信你关于 autosavesInPlace
的问题已经在评论中得到了回答......
关于swift - 从 Storyboard启动的初始应用程序无法调用 NSDocument init,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44187861/