首页 > 解决方案 > 恢复嵌套的 NSDocuments

问题描述

我正在为 MacOS 开发类似 Xcode 的 IDE。IDE 打开源文件(的实例TextDocument)并具有单独的项目文件(ProjectDocument包含项目设置的实例。两者都是NSDocument.

打开源文件时,WindowsController 和 contentViewController 仍然需要访问项目文件。

我最初解决这个问题的方法是var project: ProjectDocument?向 TextDocument 添加一个属性。这样每个源文件都有一个指向项目文档的指针。视图控制器的representedObject属性设置为文本文档。

这在创建、打开和保存文件时效果很好。

但是,重新打开应用程序后恢复窗口并非完美无缺。

TextDocument (设置为representedObject)得到正确恢复,但project属性没有。确实保存了一些东西,因为在方法中if coder.containsValue(forKey: "project")返回,但随后返回。好像编码与解码预期的格式不同。truerestoreState(with coder: NSCoder)self.project = coder.decodeObject(forKey: "project") as? ProjectDocumentnil

如果我更改 ProjectDocument 使其继承自NSObject而不是NSDocument,则项目确实会正确恢复。

所以问题似乎是编码NSDocument实例。

我也尝试将项目文件存储为视图控制器的单独属性,但这有同样的问题。不知何故,NSDocuments 似乎不喜欢被编码。

final class TextDocument: NSDocument {
    @objc var project: ProjectDocument? = nil

    override func encodeRestorableState(with coder: NSCoder) {
        coder.encodeConditionalObject(self.project, forKey: "project")
        super.encodeRestorableState(with: coder)
    }

    override func restoreState(with coder: NSCoder) {        
        super.restoreState(with: coder)
        if coder.containsValue(forKey: SerializationKey.project) {
            self.project = coder.decodeObject(forKey: "project") as? ProjectDocument // Is always nil
        }
    }
}

// NSDocument subclass can't be restored
final class ProjectDocument: NSDocument {

}

// NSObject subclass can.

final class ProjectDocument: NSObject, NSCoding {

}

我希望恢复的project财产。TextDocument它不是

标签: swiftmacosnsdocumentstate-restorationnswindowrestoration

解决方案


推荐阅读