swift key-Value Observing
在swift中 只有繼承 NSObject的類才具有 kvo特性
應用 kvo 的三個步驟
- 給屬性添加
dynamic
修飾語 - 創(chuàng)建一個全局內容變量 用來標記觀察者
- 加入到觀察者中, 并在 deinit中 移除觀察者
完整代碼如下
import UIKit
//- [關于 kvo](https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html#//apple_ref/doc/uid/TP40014216-CH7-ID12)
class MyObjectToObsever: NSObject {
// 要觀察的屬性 用 dynamic 修飾
dynamic var myDate = NSDate()
func updateDate(){
myDate = NSDate()
}
}
// 全局變量, 用來標記通知類型 也可以不標記
private var myContext = 0
class KVODemo: NSObject {
var objectToObserver = MyObjectToObsever()
override init() {
super.init()
// 把要觀察的 屬性加入觀察中心
objectToObserver.addObserver(self, forKeyPath: #keyPath(MyObjectToObsever.myDate), options: .new, context: &myContext)
}
//當被觀察的屬性 值 發(fā)生變化時 會走這個方法
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &myContext {
if let newValue = change?[.newKey] {
print("Date changed: \(newValue)")
}
}else{
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
//記得手動移除 觀察者
deinit {
objectToObserver.removeObserver(self, forKeyPath: #keyPath(MyObjectToObsever.myDate))
}
}
dynamic關鍵字
如果您有過OC的開發(fā)經驗芍阎,那一定會對OC中@dynamic關鍵字比較熟悉爬橡,它告訴編譯器不要為屬性合成getter和setter方法勾徽。
Swift中也有dynamic關鍵字两蟀,它可以用于修飾變量或函數嚣潜,它的意思也與OC完全不同懒棉。它告訴編譯器使用動態(tài)分發(fā)而不是靜態(tài)分發(fā)巷懈。OC區(qū)別于其他語言的一個特點在于它的動態(tài)性该抒,任何方法調用實際上都是消息分發(fā),而Swift則盡可能做到靜態(tài)分發(fā)顶燕。
因此凑保,標記為dynamic的變量/函數會隱式的加上@objc關鍵字,它會使用OC的runtime機制割岛。
雖然靜態(tài)分發(fā)在效率上可能更好愉适,不過一些app分析統(tǒng)計的庫需要依賴動態(tài)分發(fā)的特性,動態(tài)的添加一些統(tǒng)計代碼癣漆,這一點在Swift的靜態(tài)分發(fā)機制下很難完成维咸。這種情況下,雖然使用dynamic關鍵字會犧牲因為使用靜態(tài)分發(fā)而獲得的一些性能優(yōu)化,但也依然是值得的癌蓖。
class Kraken {
dynamic var imADynamicallyDispatchedString: String
dynamic func imADynamicallyDispatchedFunction() {
//Hooray for dynamic dispatch!
}
}
使用動態(tài)分發(fā)瞬哼,您可以更好的與OC中runtime的一些特性(如CoreData,KVC/KVO)進行交互租副,不過如果您不能確定變量或函數會被動態(tài)的修改坐慰、添加或使用了Method-Swizzle,那么就不應該使用dynamic關鍵字用僧,否則有可能程序崩潰结胀。