102*_*4jp 5 cocoa nsdocument swift
关于基于文档的 Cocoa 应用程序,Apple 建议覆盖 NSDocumentinit(contentsOf:ofType:)来自定义内容,因此似乎是一个覆盖的好地方。
您可以覆盖此方法以自定义重新打开自动保存的文档。
然而在 Swift 上,这实际上是不可能的,因为 superinit(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
}
Run Code Online (Sandbox Code Playgroud)
当我在Objective-C中编写基于文档的应用程序时,我使用这种方法,即initWithContentsOfURL:ofType:error:只为使用现有文件打开的文档准备一些文件相关的属性,而不为新的空白文档或恢复的文档准备一些文件相关的属性。
它不能简单地用 NSDocument 代替,read(from:ofType)因为它不仅会在文档打开时被调用,而且在每次重新加载文档时都会被调用(例如 Revert)。
也不可能在 normal 上做我的事情init(),因为fileURL当时还没有设置属性。
init() {
super.init()
self.fileURL // <- returns nil
}
Run Code Online (Sandbox Code Playgroud)
我知道一个方便的初始化程序必须调用一个指定的初始化程序,但是init(contentsOf:ofType:)与init(type:). (如何在 Swift 中初始化一个新的 NSDocument 实例?)
像这样的东西?(但不确定)
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
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是:在打开文档时只对 fileURL 做一次操作的合适点在哪里?
对于解决方法,我目前覆盖makeDocument(withContentsOf:ofType:了 NSDocumentController 子类,并从原始文档的初始值设定项中创建一个文档,在其中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
}
Run Code Online (Sandbox Code Playgroud)
据我所知,这绝对是当前 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()
}
Run Code Online (Sandbox Code Playgroud)
我刚刚开始一个NSPersistentDocument子类,目前效果很好。
| 归档时间: |
|
| 查看次数: |
608 次 |
| 最近记录: |