NSPersistentDocument、Swift、macOS 和故事板——如何获取 managedObjectContext?

NSPersistentDocument, Swift, macOS, and storyboards — how to get the managedObjectContext?

自从我处理 CoreData 和 macOS 以来已经有一段时间了,回到 xib 和 nibs 的时代。使用 xib,有一个“文件所有者”可以让您访问您的文档和 managedObjectContext。简单。

对于 NSPersistentDocument 和我的情节提要,我遇到了一些先有鸡还是先有蛋的问题。在我的文档 class 中,从 NSPersistentDocument 子 class 编辑,我有以下内容:

override func makeWindowControllers() {
    // Returns the Storyboard that contains your Document window.
    let storyboard = NSStoryboard(name: "Main", bundle: nil)
    let windowController = storyboard.instantiateControllerWithIdentifier("Document Window Controller") as! NSWindowController // <- when I need the moc
    self.addWindowController(windowController)
    windowController.contentViewController!.representedObject = self // <- when I set the representedObject
}

这似乎是包括 Apple 在内的许多人的建议。

我的问题是:在MainViewController中,我想要一个对象控制器,它需要绑定到managedObjectContext,但是当它需要有managedObjectContext时,我还没有将representedObject设置为self。所以抛出异常。在 makeWindowControllers 方法的末尾设置 representedObject 为时已晚,但无论如何我看不到要更早地获取它。

好的。所以。我不知道昨晚发生了什么,但我无法让它工作。

今天早上,我重新阅读了有关 representedObject 的文档:

The representedObject property is key-value coding and key-value observing compliant. When you use the represented object as the file's owner of a nib file, you can bind controls to the file's owner using key paths that start with the string representedObject.

文档清楚地告诉我,魔术就在 representedObject 中。所以我确保我的 makeWindowControllers 方法如上所示,并且我确保我的情节提要中的对象控制器与文档所说的一样。

我对路径有一点点 (!) 并不感到惊讶,因为 representedObject 只是一个 AnyObject。

然后我尽职尽责地启动了该应用程序,完全期望它无法运行。

但它奏效了。不知道为什么昨天没有,但我对已经失去的时间无能为力。

跟进:作为实验,我尝试了昨天的一个曲折。为了摆脱 (!) 并方便地引用 moc,我将此方法添加到 MainViewController:

var moc:NSManagedObjectContext? {
    if let doc = self.representedObject as? Document {
        return doc.managedObjectContext
    }
    return nil
}

然后我使用“self.moc”作为我的对象控制器的模型键路径。这没有用,并且抛出了熟悉的异常。将模型密钥路径恢复为“self.representedObject.managedObjectContext”,一切正常。 ……就像魔法一样。