iOS-设计模式-观察者模式-KVO
2019獨角獸企業重金招聘Python工程師標準>>>
KVO:
Key Value Observe,鍵值觀察:用于監聽屬性的變化,觀察者在鍵值改變時會得到通知。
KVO簡單使用:
//KVO的使用也很簡單,就是簡單的3步。1.注冊需要觀察的對象的屬性addObserver:forKeyPath:options:context:2.實現observeValueForKeyPath:ofObject:change:context:方法,這個方法當觀察的屬性變化時會自動調用3.取消注冊觀察removeObserver:forKeyPath:context://不需要在被觀察對象中添加任何代碼判斷是否有觀察者:
[object?observationInfo];//如果沒有返回nullKVO內部原理:
當你觀察一個對象時,一個新的類會動態被創建。這個類繼承自該對象的原本的類,并重寫了被觀察屬性的 setter 方法。自然,重寫的 setter 方法會負責在調用原 setter 方法之前和之后,通知所有觀察對象值的更改。最后把這個對象的 isa 指針 ( isa 指針告訴 Runtime 系統這個對象的類是什么 ) 指向這個新創建的子類,對象就神奇的變成了新創建的子類的實例。
原來,這個中間類,繼承自原本的那個類。不僅如此,Apple 還重寫了 -class 方法,企圖欺騙我們這個類沒有變,就是原本那個類
簡而言之就是:
1、當一個object有觀察者時,動態創建這個object的類的子類
2、對于每個被觀察的property,重寫其set方法
3、在重寫的set方法中調用- willChangeValueForKey:和- didChangeValueForKey:通知觀察者
4、當一個property沒有觀察者時,刪除重寫的方法
5、當沒有observer觀察任何一個property時,刪除動態創建的子類
示例:
@interface?myPerson?:?NSObject?? {??NSString?*_name;??int??????_age;??int??????_height;??int??????_weight;?? }?? @end??@interface?testViewController?:?UIViewController?? @property?(nonatomic,?retain)?myPerson?*testPerson;??-?(IBAction)onBtnTest:(id)sender;?? @end??-?(void)testKVO?? {??testPerson?=?[[myPerson?alloc]?init];??[testPerson?addObserver:self?forKeyPath:@"height"?options:NSKeyValueObservingOptionNew?context:nil];??/*NSKeyValueObservingOptionNew?把更改之前的值提供給處理方法NSKeyValueObservingOptionOld?把更改之后的值提供給處理方法NSKeyValueObservingOptionInitial?把初始化的值提供給處理方法,一旦注冊,立馬就會調用一次。通常它會帶有新值,而不會帶有舊值。NSKeyValueObservingOptionPrior?分2次調用。在值改變之前和值改變之后*/ }??-?(void)observeValueForKeyPath:(NSString?*)keyPath?ofObject:(id)object?change:(NSDictionary?*)change?context:(void?*)context?? {??if?([keyPath?isEqualToString:@"height"])?{??NSLog(@"Height?is?changed!?new=%@",?[change?valueForKey:NSKeyValueChangeNewKey]);??}?else?{??[super?observeValueForKeyPath:keyPath?ofObject:object?change:change?context:context];??}?? }??-?(IBAction)onBtnTest:(id)sender?{??int?h?=?[[testPerson?valueForKey:@"height"]?intValue];??????[testPerson?setValue:[NSNumber?numberWithInt:h+1]?forKey:@"height"];??NSLog(@"person?height=%@",?[testPerson?valueForKey:@"height"]);?? }??-?(void)dealloc?? {??[testPerson?removeObserver:self?forKeyPath:@"height"?context:nil];??[super?dealloc];?? }上述講解:
第一段代碼聲明了myPerson類,里面有個_height的屬性。在testViewController有一個testPerson的對象指針。
? ? ? 在testKVO這個方法里面,我們注冊了testPerson這個對象height屬性的觀察,這樣當testPerson的height屬性變化時,會得到通知。在這個方法中還通過NSKeyValueObservingOptionNew這個參數要求把新值在dictionary中傳遞過來。
? ? ? 重寫了observeValueForKeyPath:ofObject:change:context:方法,這個方法里的change這個NSDictionary對象包含了相應的值。
? ? ? 需要強調的是KVO的回調要被調用,屬性必須是通過KVC的方法來修改的,如果是調用類的其他方法來修改屬性,這個觀察者是不會得到通知的。
來源:
http://blog.csdn.net/sakulafly/article/details/14084183
http://my.oschina.net/caijunrong/blog/510701?fromerr=m1emHKKJ
http://my.oschina.net/zhaodacai/blog/653810?fromerr=YUxKnfQj
轉載于:https://my.oschina.net/liuchuanfeng/blog/667502
總結
以上是生活随笔為你收集整理的iOS-设计模式-观察者模式-KVO的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用RawSocket进行网络抓包
- 下一篇: Leetcode题目:Rectangle