1.KVO概念
KVO即鍵值觀察,它提供一種機制,當被觀察的對象的屬性發(fā)生改變后,對象會接收到通知,從而做出相應的改變。
2.KVO實現(xiàn)原理
每一個對象都有一個isa指針,這個對象根據(jù)isa指針去尋找它所歸屬的類(具體可看我的這一篇文章[http://www.lxweimin.com/p/a894d5968ac1] ),當我們給一個對象注冊觀察者的時候,系統(tǒng)會在運行時給這個對象創(chuàng)建一個子類,這個子類繼承于當前對象歸屬的類,并把當前對象的isa指針指向這個子類,于是當前對象就變成了這個子類的一個實例。那么這個子類內(nèi)部做了什么操作呢?其實這個子類重寫了set方法,當原對象在調(diào)用set方法賦值的時候,會根據(jù)isa指針到新建子類的方法列表去尋找set方法的IMP,此時這個重寫的set方法會對所有觀察這個屬性的對象發(fā)出通知,于是原有的對象會作出改變。
KVO鍵值觀察依賴于NSObject的兩個方法:willChangeValueForKey和didChangevlueForKey,即在鍵值改變前后分別調(diào)用這兩個方法,然后在這兩個方法的中間調(diào)用父類set方法賦值。
3.KVO的特點
由于KVO內(nèi)部實現(xiàn)的原理是重寫了set方法,因此只有當被觀察對象的屬性調(diào)用set方法賦值的時候才會執(zhí)行KVO的的回調(diào)方法。所以如果直接對屬性的成員變量直接賦值那么不會觸發(fā)KVO。
4.KVO的調(diào)用步驟
1.注冊觀察者
2.在回調(diào)方法中處理事件
3.移除觀察者
5.代碼實踐
self.changeStr = @"您好";
[self addObserver:self forKeyPath:@"changeStr" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
self.changeStr = @"大家都好";
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
NSLog(@"被改變的屬性是%@",keyPath);
NSString *str = [change objectForKey:NSKeyValueChangeNewKey];
NSString *odlStr = [change objectForKey:NSKeyValueChangeOldKey];
NSLog(@"舊屬性是%@",odlStr);
NSLog(@"新屬性是%@",str);
}
輸出結果:
屏幕快照 2017-03-13 15.28.29.png