我用.Old |创建了一个观察者.新的选择.在handler方法中,我尝试在值之后获取,但编译器抱怨:’Nsstring’不能转换为’NSDictionaryIndex:NSObject,AnyObject
override func observeValueForKeyPath(keyPath: String!,ofObject object: AnyObject!,change: [NSObject : AnyObject]!,context: UnsafeMutablePointer<Void>) {
let approvedOld = change[NSkeyvalueChangeOldKey] as Bool
let approvednew = change[NSkeyvalueChangeNewKey] as Bool
iOS 11和Swift> 4.1
iOS 11和Swift 4为KVO带来了重大变化.
>类应采用@objcmembers注释,以便使KVO或KVO无声地失败.
>必须将要观察的变量声明为动态.
这是更新的实现,
@objcmembers
class Approval: NSObject {
dynamic var approved: Bool = false
let ApprovalObservingContext = UnsafeMutableRawPointer(bitPattern: 1)
override init() {
super.init()
addobserver(self,forKeyPath: #keyPath(approved),options: [.new,.old],context: ApprovalObservingContext)
}
override func observeValue(forKeyPath keyPath: String?,of object: Any?,change: [NSkeyvalueChangeKey : Any]?,context: UnsafeMutableRawPointer?) {
guard let observingContext = context,observingContext == ApprovalObservingContext else {
super.observeValue(forKeyPath: keyPath,of: object,change: change,context: context)
return
}
guard let change = change else {
return
}
if let oldValue = change[.oldKey] {
print("Old value \(oldValue)")
}
if let newValue = change[.newKey] {
print("New value \(newValue)")
}
}
deinit {
removeObserver(self,forKeyPath: #keyPath(approved))
}
}
KVO还有一个新的基于bock的api,就像这样工作,
@objcmembers
class Approval: NSObject {
dynamic var approved: Bool = false
var approvalObserver: NSkeyvalueObservation!
override init() {
super.init()
approvalObserver = observe(\.approved,.old]) { _,change in
if let newValue = change.newValue {
print("New value is \(newValue)")
}
if let oldValue = change.oldValue {
print("Old value is \(oldValue)")
}
}
}
}
基于块的api看起来超级好用且易于使用.此外,keyvalueObservation在deinited时无效,因此不需要删除观察者.
Swift 2.0和iOS< 10 使用Swift 2.0,这是一个使用KVO的类的完整实现,
class Approval: NSObject {
dynamic var approved: Bool = false
let ApprovalObservingContext = UnsafeMutablePointer<Int>(bitPattern: 1)
override init() {
super.init()
addobserver(self,forKeyPath: "approved",options: [.Old,.New],context: ApprovalObservingContext)
}
override func observeValueForKeyPath(keyPath: String?,ofObject object: AnyObject?,change: [String : AnyObject]?,context: UnsafeMutablePointer<Void>) {
if let theChange = change as? [String: Bool] {
if let approvedOld = theChange[NSkeyvalueChangeOldKey] {
print("Old value \(approvedOld)")
}
if let approvednew = theChange[NSkeyvalueChangeNewKey]{
print("New value \(approvednew)")
}
return
}
super.observeValueForKeyPath(keyPath,ofObject: object,context: context)
}
deinit {
removeObserver(self,forKeyPath: "approved")
}
}
let a = Approval()
a.approved = true