Skip to content

Instantly share code, notes, and snippets.

@saagarjha
Forked from jeanetienne/MyDocument.swift
Last active May 30, 2018 08:16
Show Gist options
  • Save saagarjha/aeb3001f5785e21a4fa4ccfb7cffef14 to your computer and use it in GitHub Desktop.
Save saagarjha/aeb3001f5785e21a4fa4ccfb7cffef14 to your computer and use it in GitHub Desktop.
//
// Logic necessary to implement a "closing handler" for a NSDocument
//
// This is inspired by:
// - https://stackoverflow.com/questions/49343307/best-practice-to-implement-canclosewithdelegateshouldclosecontextinfo
// - https://github.com/keith/radars/blob/master/NSDocumentSwiftAnnotations/NSDocumentSwiftAnnotations/Document.swift
// Keith's supporting documentation for his radar submission: http://www.openradar.me/33422662
// Documentation:
// - https://developer.apple.com/library/content/releasenotes/AppKit/RN-AppKitOlderNotes/
// Paragraph called: "Advice for Overriders of Methods that Follow the delegate:didSomethingSelector:contextInfo: Pattern"
//
// I'm not even sure I understand all that's happening here, use it at you own risk!
//
class MyDocument: NSDocument {
private /* weak */ var delegate: NSObjectProtocol?
private var shouldCloseSelector: Selector?
override func canClose(withDelegate delegate: Any, shouldClose shouldCloseSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
self.delegate = delegate as? NSObjectProtocol
self.shouldCloseSelector = shouldCloseSelector
super.canClose(withDelegate: delegate, shouldClose: shouldCloseSelector, contextInfo: contextInfo)
}
@objc func document(_ document: NSDocument, shouldClose: Bool, contextInfo: UnsafeMutableRawPointer?) {
typealias FunctionSignature = (@convention(c) (AnyObject?, Selector?, NSDocument, Bool, UnsafeMutableRawPointer?) -> Void)?
let implementation = shouldCloseSelector.flatMap { unsafeBitCast(class_getMethodImplementation(type(of: delegate) as? AnyClass, $0), to: FunctionSignature.self) }
implementation?(delegate, shouldCloseSelector, self, shouldClose, contextInfo)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment