【发布时间】:2017-10-26 12:54:59
【问题描述】:
我使用 Xcode 模板编写了一个带有故事板的 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 在应用程序在文档的某个实例上启动后被调用了 3 次
- 当我使用 cmd-N(即 File->New 和因此 newDocument())创建一个新文档时,autosavesInPlace 又被调用了 3 次,然后执行文档初始化!
- 我从来没有看到对 makeWindowControllers() 的调用
我的 NSDocument 子类名为 Simulation。异常似乎是在最初的启动中有一些绕过 Simulation.init 的魔法,但此后每次创建文档+窗口时都调用它。
这是我的问题:
- 为什么初始启动不调用 Simulation.init()?
- 当只有那个初始的、看似部分构造的窗口时,autosavesInPlace 如何找到要调用的模拟实例?
【问题讨论】:
-
autosavesInPlace是一个类方法,它在类上调用,而不是在实例上调用。你实现applicationShouldOpenUntitledFile了吗? -
很糟糕,我错过了
autosavesInPlace作为类函数。我猜这不是我的日子。无论如何,我还没有实现applicationShouldOpenUntitledFile。我在应用程序委托中这样做了,并在我在那里时为其合作伙伴applicationOpenUntitledFile提供了一个存根,并运行了应用程序。两者都没有被调用 - 当我启动应用程序时没有调用,也没有调用 cmd-N。 -
@Willeke - 具体来说,当我启动应用程序时,我看到了这个(在 VC 中添加了打印)(我无法格式化为代码!)` "VC.swift->init(coder:调用”“VC.swift->viewDidLoad() 调用”“VC.swift->viewWillAppear() 调用”“VC.swift->viewDidAppear() 调用”` 但是,使用 cmd-N 我得到这个:`“模拟。 swift->init(type:) 调用,类型:Effie.Simulation" "Simulation.swift->init() 调用" "Simulation.swift->makeWindowControllers() 调用" "VC.swift->init(coder: 调用" “VC.swift->viewDidLoad() 调用” “VC.swift->viewWillAppear() 调用” “VC.swift->viewDidAppear() 调用”`
-
我们无法猜测故事板中未识别的变化是什么。创建一个新的测试项目并进行比较。休息一下
init(type:)。 -
我也猜不出来,并且初始窗口没有调用 init(type:) - 这就是我无法弄清楚的原因!
标签: swift macos storyboard init nsdocument