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

Initial app launch from storyboard fails to call NSDocument init

我使用 Xcode 模板编写了一个带有故事板的 macOS 文档类型应用程序,并且沿线某处初始应用程序启动与文档之间的关联与预期模式不同,例如我期望 none 的 NSDocument 初始值设定项在应用程序首次启动时被调用(但此后每个新的 window 被调用)。

我已经将所有四个记录的 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
    }
}

None 的 init 在应用程序启动时显示 debugPrint 输出。应用程序 window 在启动时创建成功,没有 明显的 文档关联。

但是,我注意到一些我无法解释的非常奇怪的行为:

  1. 尽管我没有看到任何 init 调用,但在应用程序在文档的某个实例上启动后,autosavesInPlace 被调用了三次
  2. 当我使用 cmd-N(即 File->New,因此是 newDocument())创建新文档时,autosavesInPlace 又被调用了三次,然后执行了文档初始化!
  3. 我从未见过调用 makeWindowControllers()

我的 NSDocument 子类名为 Simulation。异常似乎是在初始启动中有一些绕过 Simulation.init 的魔法,但此后每次创建 document+window 时都会调用它。

这是我的问题:

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

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

选中 Is Initial Controller 将导致应用程序在任何 NSDocument/NSDocumentController "magic" 发生之前实例化一个 window 控制器。 Presentation: Multiple 应该选择连贯性,尽管它可能不会真正产生影响。

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

我相信你关于 autosavesInPlace 的问题已经在评论中得到了回答…