Skip to content

Instantly share code, notes, and snippets.

@kemchenj
Forked from chriseidhof/kvo-binding.swift
Last active September 13, 2017 16:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kemchenj/0665f3f77f8a85f38340aaa5746c5e58 to your computer and use it in GitHub Desktop.
Save kemchenj/0665f3f77f8a85f38340aaa5746c5e58 to your computer and use it in GitHub Desktop.
通过 Swift 4 新增的 KeyPath,让 NSObject 拥有了类型安全的 KVO-Binding https://twitter.com/chriseidhof/status/907232916555661312
import Foundation
final class Sample: NSObject {
@objc dynamic var name: String = ""
}
class MyObj: NSObject {
@objc dynamic var test: String = ""
}
let sample = Sample()
let other = MyObj()
let observation = sample.bind(\Sample.name, to: other, \.test)
sample.name = "NEW"
other.test
other.test = "HI"
sample.name
import Foundation
extension NSObjectProtocol where Self: NSObject {
func observe<A, Other>(_ keyPath: KeyPath<Self,A>,
writeTo other: Other,
_ otherKeyPath: ReferenceWritableKeyPath<Other,A>)
-> NSKeyValueObservation
where A: Equatable, Other: NSObjectProtocol
{
return self.observe(keyPath, options: .new) { _, change in
guard let newValue = change.newValue,
other[keyPath: otherKeyPath] != newValue else {
return // no change
}
other[keyPath: otherKeyPath] = newValue
}
}
func bind<A, Other>(_ keyPath: ReferenceWritableKeyPath<Self,A>,
to other: Other,
_ otherKeyPath: ReferenceWritableKeyPath<Other,A>)
-> (NSKeyValueObservation, NSKeyValueObservation)
where A: Equatable, Other: NSObject
{
let one = self.observe(keyPath, writeTo: other, otherKeyPath)
let two = other.observe(otherKeyPath, writeTo: self, keyPath)
return (one,two)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment