Last active
May 5, 2017 12:33
-
-
Save rcharlton/87d1a2768d78ac7be3c6927a38daafe4 to your computer and use it in GitHub Desktop.
KeyValue Observing in Swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
public final class Observer: NSObject { | |
public let subject: NSObject | |
public let keyPath: String | |
public let didChange: ([NSKeyValueChangeKey : Any]) -> Void | |
/* | |
private static var context = 0 | |
private var context: UnsafeMutableRawPointer { | |
return UnsafeMutableRawPointer(&Observer.context) | |
} | |
*/ | |
public init(_ subject: NSObject, | |
keyPath: String, | |
didChange: @escaping ([NSKeyValueChangeKey : Any]) -> Void) { | |
self.subject = subject | |
self.keyPath = keyPath | |
self.didChange = didChange | |
super.init() | |
subject.addObserver(self, | |
forKeyPath: keyPath, | |
options: [.initial, .new], | |
context: nil) | |
} | |
override public func observeValue( | |
forKeyPath keyPath: String?, | |
of object: Any?, | |
change: [NSKeyValueChangeKey : Any]?, | |
context: UnsafeMutableRawPointer?) { | |
/* | |
if let change = change, | |
context == self.context { | |
didChange(change) | |
} else { | |
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) | |
} | |
*/ | |
if let change = change { | |
didChange(change) | |
} | |
} | |
deinit { | |
subject.removeObserver(self, forKeyPath: keyPath, context: nil) | |
} | |
} | |
let progress = Progress(totalUnitCount: 2) | |
let observer = Observer(progress, keyPath: #keyPath(Progress.fractionCompleted)) { | |
change in | |
if let newValue = change[.newKey] { | |
print("newValue: \(newValue)") | |
} | |
} | |
progress.completedUnitCount = 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment