从故事板启动的初始应用程序无法调用NSDocument init

时间:2017-05-25 18:53:18

标签: swift macos storyboard init nsdocument

我已经使用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
    }
}

当应用程序启动时,没有任何内容显示debugPrint输出。应用程序窗口在启动时成功创建,没有明显的文档关联。

然而,我注意到一些我无法解释的奇怪行为:

  1. 虽然我没有看到初始化调用,但是在应用程序启动文档的某个实例后,会调用autosavesInPlace三次
  2. 当我使用cmd-N(即File-> New和newDocument())来创建新文档时,再调用autosavesInPlace三次,然后执行文档init!
  3. 我从未看到过调用makeWindowControllers()
  4. 我的NSDocument子类名为Simulation。异常似乎是初始启动中有一些神奇的东西绕过了Simulation.init,但之后调用了每个文档+窗口。

    以下是我的问题:

    1. 为什么初始启动不会调用Simulation.init()?
    2. 当只有初始的,看似部分构建的窗口时,autosavesInPlace如何找到要调用的模拟实例?

1 个答案:

答案 0 :(得分:6)

在故事板中,确保您的Window Controller及其内容视图控制器未选中Is Initial ControllerPresentation在属性检查器中设置为Multiple

Window Controller Attributes Inspector image

View Controller Attributes Inspector image

检查Is Initial Controller将导致应用程序在任何NSDocument / NSDocumentController“魔法”发生之前实例化一个窗口控制器。应该选择Presentation: Multiple来保持连贯性,尽管它可能没有什么区别。

另外,请确保在Info.plist中正确设置了文档类型,尤其是NSDocumentClass密钥(应包含$(PRODUCT_MODULE_NAME).Simulation)。

我相信您的autosavesInPlace问题已在评论中得到解答......