关于基于文档的Cocoa应用程序,Apple建议覆盖NSDocument的init(contentsOf:ofType:)
以自定义内容,因此它似乎是一个优先覆盖的地方。
您可以覆盖此方法以自定义重新打开自动保存的文档。
比照init(contentsOf:ofType:) - NSDocument | Apple Developer Documentation
但是在Swift上,实际上这是不可能的,因为在init(contentsOf:ofType:)
中无法调用超级init(contentsOf:ofType:)
,因为此初始值设定项是便捷初始值设定项之一。
convenience init(contentsOf url: URL, ofType typeName: String) throws {
try super.init(contentsOf: url, ofType: typeName) // <- this marked as error
}
当我在Objective-C中编写基于文档的应用程序时,我使用此方法,即initWithContentsOfURL:ofType:error:
,仅为使用现有文件打开的文档准备一些与文件相关的属性,但不为新的空白文档准备或者恢复文件。
不能简单地用NSDocument read(from:ofType)
替换它,因为它不仅会在文档打开时调用,而且每次重新加载文档时都会被调用(例如Revert)。
也无法在正常init()
上执行我的操作,因为此时尚未设置fileURL
属性。
init() {
super.init()
self.fileURL // <- returns nil
}
我知道一个方便初始值设定项必须调用一个指定的初始值设定项,但是init(contentsOf:ofType:)
比init(type:)
更模糊超级行为是非常复杂和模糊的。 (How do I initialise a new NSDocument instance in Swift?)
这样的东西? (但不确定)
convenience init(contentsOf url: URL, ofType typeName: String) throws {
self.init()
self.fileURL = url
self.fileType = typeName
self.fileModificationDate = (try? FileManager.default.attributesOfItem(atPath: url.path))?[.modificationDate] as? Date
}
所以,我的问题是:在文档打开时,只有一次使用fileURL做适当的点?
对于变通方法,我当前覆盖了NSDocumentController子类的makeDocument(withContentsOf:ofType:
,并从原始文档的初始化程序中创建了一个文档,其中self.init(contentsOf: url, ofType: typeName)
被调用。
我上面提到的第一个解决方法并不安全。我发现在分离的函数中进行额外的初始化会更好。
override func makeDocument(withContentsOf url: URL, ofType typeName: String) throws -> NSDocument {
let document = try super.makeDocument(withContentsOf: url, ofType: typeName)
(document as? Document)?.additionalInit() // call original func
return document
}
答案 0 :(得分:0)
肯定是当前swift的一个缺点,据我所知,在Swift开发中讨论过。然而,可以轻松实现覆盖。从Apple文档中可以清楚地看到read(from:, typeName)
被调用,fileURL
,fileType
和fileModificationDate
已设置。这是一些简单的调用,例如:
convenience init(contentsOf url: URL, ofType typeName: String) throws {
self.init()
try self.read(from:url, ofType:typeName)
self.fileURL = url
self.fileType = typeName
self.fileModificationDate = Date()
//methods and sets values for the fileURL, fileType, and fileModificationDate properties.
self.undoManager?.disableUndoRegistration()
self.initializeGroups(false)
self.managedObjectContext?.processPendingChanges()
self.undoManager?.enableUndoRegistration()
}
我刚刚开始一个NSPersistentDocument
子类,现在效果很好。