Skip to content

Instantly share code, notes, and snippets.

@swillits
Created February 1, 2017 20:57
Show Gist options
  • Save swillits/93206997e7d1bff4d08e24e23173820e to your computer and use it in GitHub Desktop.
Save swillits/93206997e7d1bff4d08e24e23173820e to your computer and use it in GitHub Desktop.
class Receptionist: NSObject {
typealias KVOReceptionistBlock = (Info) -> ()
private var opQueue: OperationQueue? = nil
private var kvoHandler: KVOReceptionistBlock! = nil
private var kvoObject: NSObject! = nil
private var kvoKeyPath: String! = nil
private var kvoContext: Int? = nil
private var activeLock = QueueLock()
private var _active = true
var active: Bool {
get {
return activeLock.getting {
return self._active
}
}
set {
activeLock.around {
self._active = newValue
}
}
}
struct Info {
let object: NSObject
let keyPath: String
let change: [NSKeyValueChangeKey : Any]?
}
init(forKeyPath keyPath: String, of object: NSObject, options: NSKeyValueObservingOptions, queue: OperationQueue?, handler: @escaping KVOReceptionistBlock) {
kvoHandler = handler
kvoObject = object
kvoKeyPath = keyPath
opQueue = queue
super.init()
kvoObject.addObserver(self, forKeyPath: kvoKeyPath, options: options, context: &kvoContext)
}
convenience init(forKeyPath keyPath: String, of object: NSObject, handler: @escaping KVOReceptionistBlock) {
self.init(forKeyPath: keyPath, of: object, options: NSKeyValueObservingOptions(), queue: nil, handler: handler)
}
deinit {
kvoObject.removeObserver(self, forKeyPath: kvoKeyPath, context: &kvoContext)
}
@objc override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &kvoContext {
if keyPath == kvoKeyPath {
if let handler = kvoHandler, active {
let info = Info(object: kvoObject, keyPath: kvoKeyPath, change: change)
if let queue = opQueue {
queue.addOperation {
handler(info)
}
} else {
handler(info)
}
}
}
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment