1,在寫swift的KVO的過程當中,其不能監聽基本數據類型的屬性,若想監聽需將其改爲NSNumber類型,或其它類型,不然監聽的代理方法不走。html
2,在寫swift的KVO的過程當中,被監聽的屬性必須用「dynamic」修飾,不然監聽的代理方法不走。ios
3,在寫swift的KVO的過程當中,要保證監聽者和被監聽者同時存在(考慮到其生命週期)。swift
4,在寫swift的KVO的過程當中,要確保最後移除觀察者,防止內存泄露。app
class MyObjectToObserve: NSObject { dynamic var myDate = NSDate() func updateDate() { myDate = NSDate() } } private var myContext = 0 class MyObserver: NSObject { var objectToObserve = MyObjectToObserve() override init() { super.init() objectToObserve.addObserver(self, forKeyPath: "myDate", options: .New, context: &myContext) } override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [NSObject : AnyObject]?, context: UnsafeMutablePointer<Void>) { if context == &myContext { if let newValue = change?[NSKeyValueChangeNewKey] { print("Date changed: \(newValue)") } } else { super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) } } deinit { objectToObserve.removeObserver(self, forKeyPath: "myDate", context: &myContext) } }
Swift 中能夠爲一個屬性設置屬性觀察器,能夠說是內建的 KVO 觀察,只不過只限於對自身屬性的觀察。看起來像這個樣子:ide
class StepCounter { var totalSteps: Int = 0 { willSet(newTotalSteps) { print("About to set totalSteps to \(newTotalSteps)") } didSet { if totalSteps > oldValue { print("Added \(totalSteps - oldValue) steps") } } } }
屬性觀察器只在在初始化完成後觸發,並且不限於 NSObject 的子類,Swift 中全部的 Class, Struct, Enum 均可以使用。
Swift 內建的Array, Dictionary, Set 等都是值類型,對其內容的修改包括添加,刪除,替換元素也會觸發屬性觀察器。ui