iOS中的KVO用起來還是蠻爽的玩讳,特別適合用在Model更改后刷新UI等操作,可以很方便的監(jiān)聽一個對象屬性值的變化絮姆,只需要對目標(biāo)對象添加觀察者即可
了解了基本操作后羊壹,我們再深入了解下它是如何實現(xiàn)的
那我們從addObserver函數(shù)開始,函數(shù)接受四個參數(shù)叁执,分別是:
observer:注冊KVO的對象茄厘,且需要實現(xiàn)了observeValueForKeyPath:ofObject:change:context:方法
keyPath: 接受消息的關(guān)鍵路徑,不能為空谈宛,可在接受函數(shù)中通過判斷改值次哈,篩選被觀察的對象
options:設(shè)置通知方式
context:傳遞給接受函數(shù)的內(nèi)容,可為nil
其他沒什么說的吆录,主要說一下options這個參數(shù)窑滞,該參數(shù)接受NSKeyValueObservingOptions類型的枚舉,總共有一下四個類型:NSKeyValueObservingOptionNew //在接收器chagne參數(shù)中傳遞被修改后的新值
NSKeyValueObservingOptionOld //在接收器change參數(shù)中傳遞被修改前的舊值
NSKeyValueObservingOptionInitial //在注冊觀察者時恢筝,會先向接受者發(fā)送一次消息
-
NSKeyValueObservingOptionPrior //在被觀察對象修改前和修改后哀卫,都向接收器發(fā)送一次消息
了解了注冊觀察者的詳細后,下面我們來對比下注冊觀察者和未注冊觀察的內(nèi)存關(guān)系對比
未注冊的對象
從圖中我們可以看到撬槽,未添加的KVO監(jiān)
聽的對象此改,isa直接指向它的類Person
下面看下注冊了觀察者的對象
可以看到在對象和類中間多了一個NSKVONotifyingPersonClass,該類是由runtime動態(tài)生成侄柔,在我們?nèi)ソo對象sam的age屬性賦值時共啃,setAge方法會調(diào)用Foundation中的_NSSetIntValueAndNotify方法占调,_NSSetIntValueAndNotify方法內(nèi)部會依次調(diào)用
willChangeValueForKey
super setAge
didChangeValueForKey
(如果需要驗證以上調(diào)用順序,我們可以在Person內(nèi)重寫以上方法驗證)
隨后會向接收器發(fā)送消息移剪,也就是我們上面所說的observeValueForKeyPath:ofObject:change:context監(jiān)聽函數(shù)究珊。