【发布时间】:2016-06-30 13:53:31
【问题描述】:
我试图弄清楚如何评估func observeValue(forKeyPath... 中的[NSKeyValueChangeKey : AnyObject] 更改字典参数。我在操场上有以下代码以及我评估更改字典的方式我总是最终认为更改是 NSKeyValueChange.setting (这绝对是错误的)。
评估变化字典的正确方法是什么?
import Foundation
class KVOTester: NSObject {
dynamic var items = [Int]() // Observe via KVO
override init() {
super.init()
self.addObserver(self, forKeyPath: #keyPath(KVOTester.items), options: [], context: nil)
}
deinit {
self.removeObserver(self, forKeyPath: #keyPath(KVOTester.items))
}
func exerciseKVO() {
self.items = [Int]() // NSKeyValueChange.setting
self.items.append(1) // NSKeyValueChange.insertion
self.items[0] = 2 // NSKeyValueChange.replacement
self.items.remove(at: 0) // NSKeyValueChange.removal
}
override func observeValue(forKeyPath keyPath: String?, of object: AnyObject?, change: [NSKeyValueChangeKey : AnyObject]?, context: UnsafeMutablePointer<Void>?) {
// We are only interested in changes to our items array
guard keyPath == "items" else { return }
// #1: object is the KVOTester instance - why isn't it the items array?
// #2 I don't understand how to use the change dictionary to determine what type of change occurred. The following
// is wrong - it *always* prints "Setting".
if let changeKindValue = change?[.kindKey] as? UInt, changeType = NSKeyValueChange(rawValue: changeKindValue) {
switch changeType {
case .setting:
print("Setting")
break
case .insertion:
print("Insertion")
break
case .removal:
print("Removal")
break
case .replacement:
print("Replacement")
break
}
}
}
}
let kvoTester = KVOTester()
kvoTester.exerciseKVO()
【问题讨论】:
-
通过documentation,我的印象是
insertion、removal和replacement仅适用于Core Data更改 -
这不是真的。事实证明,要监视对阵列的更改,您需要一个兼容 kvo 的版本,可以使用
let kvoArray = self.mutableArrayValue(forKey: MediaItems")获得。对kvoArray所做的任何更改都会触发相应的 KVO 消息。
标签: swift key-value-observing swift3