我第一次尝试使用基于NSDocument的应用程序。 (Xcode 9.2,Swift 4,macOS 10.12 Sierra和Cocoa / AppKit)
我想知道实现关闭Document没有自动保存的正确方法。你能告诉我关闭NSDocument的最佳做法吗?
当用户尝试关闭文档时,将调用以下NSDocument方法。
canClose(withDelegate:shouldClose:contextInfo:)
我调试参数并找到followimng:
delegate = MyApp.Document
shouldCloseSelector = _something:didSomething:soContinue:
contextInfo = libsystem_blocks.dylib `_NSConcreteMallocBlock
显然这样的选择器不可用,所以我认为这可以在这里改变,如:
override func canClose(withDelegate delegate: Any,
shouldClose shouldCloseSelector: Selector?,
contextInfo: UnsafeMutableRawPointer?) {
let delegate : Any = self
let shouldCloseSelector : Selector = #selector(Document.document(_:shouldClose:contextInfo:))
super.canClose(withDelegate: delegate, shouldClose: shouldCloseSelector, contextInfo: contextInfo)
}
@objc func document(_ document : NSDocument, shouldClose flag : Bool,
contextInfo: UnsafeMutableRawPointer?) {
if document === self, flag {
self.cleanup() // my cleanup method
self.close() // NSDocument.close()
}
}
deinit {
Swift.print(#function, #line)
}
它似乎有用,但我想这不是正确的方法,因为忽略了原始参数(Selector / contextInfo)。
答案 0 :(得分:1)
我找到了解决方案。我希望这会对某人有所帮助。
private var closingBlock : ((Bool) -> Void)? = nil
override func canClose(withDelegate delegate: Any,
shouldClose shouldCloseSelector: Selector?,
contextInfo: UnsafeMutableRawPointer?) {
let obj : AnyObject = delegate as AnyObject
let Class : AnyClass = object_getClass(delegate)!
let method = class_getMethodImplementation(Class, shouldCloseSelector!)
typealias signature =
@convention(c) (AnyObject, Selector, AnyObject, Bool, UnsafeMutableRawPointer?) -> Void
let function = unsafeBitCast(method, to: signature.self)
self.closingBlock = {[unowned obj, shouldCloseSelector, contextInfo] (flag) -> Void in
function(obj, shouldCloseSelector!, self, flag, contextInfo)
}
let delegate : Any = self
let shouldCloseSelector : Selector = #selector(Document.document(_:shouldClose:contextInfo:))
super.canClose(withDelegate: delegate, shouldClose: shouldCloseSelector, contextInfo: contextInfo)
}
@objc func document(_ document : NSDocument, shouldClose flag : Bool,
contextInfo: UnsafeMutableRawPointer?) {
if flag {
self.cleanup() // my cleanup method
}
self.closingBlock?(flag)
self.closingBlock = nil
}
override func close() {
Swift.print(#function, #line, #file)
super.close()
}
deinit {
Swift.print(#function, #line, #file)
}
https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKitOlderNotes/
跟随委托的方法的覆盖者的建议:didSomethingSelector:contextInfo:Pattern
展示如何实现NSDocument方法-canCloseDocumentWithDelegate:shouldCloseSelector:contextInfo:使用Swift。必须使用Objective-C来执行NSInvocation。