一. KVO是鍵值觀察,是Objective-C對觀察者模式的實現(xiàn)瓶佳,每次當被觀察者對象的某個屬性值發(fā)生改變時芋膘,注冊的觀察者便能獲得通知
二.原理:當觀察某對象A時,KVO機制動態(tài)創(chuàng)建一個對象A當前類的子類:NSKVONotifying_A霸饲,并為這個新的子類重寫了被觀察屬性keyPath的setter方法为朋。 setter方法隨后負責通知對象屬性的改變狀況.
在這個過程中,被觀察者對象的isa指針從指向原來的A類厚脉,被KVO機制修改為指向系統(tǒng)新創(chuàng)建的子類NSKVNitifying_A類习寸,來實現(xiàn)當前類屬性值改變的監(jiān)聽 ?
isa指針的作用:每個對象都有isa指針,指向該對象的類傻工,它告訴Runtime系統(tǒng)這個對象的類是什么霞溪。所以對象注冊為觀察者時,isa指針指向新子類中捆,那么這個被觀察的對象就變成新子類的對象鸯匹,因而在該對象上對setter的調(diào)用就會調(diào)用已重寫的setter,從而激活鍵盤值通知機制
KVO的鍵值觀察通知依賴于NSObject的兩個方法:willChangeValueForKey: 和 didChangeValueForKey?
三.方法
1.注冊觀察者泄伪,實施監(jiān)聽
[person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
其中person為被觀察者對象殴蓬,他的name屬性即為被觀察者的屬性
2.在回調(diào)方法中處理屬性發(fā)生的變化
- (void)observeValueForKeyPath:(NSString *)keyPath ?ofObject:(id)object change:(NSDictionary *)change ?context:(voidvoid *)context
{
NSString *name = [object valueForKey:@"name"];
NSLog(@"new name is: %@", name);
}
只要person對象中的name發(fā)生變化,系統(tǒng)會自動調(diào)用該方法
3.移除觀察者
-(void)dealloc
{
[person removeObserver:self forKeyPath:@"name"];
}
四.擴展
1.kvo與kvc不同
KVC (鍵值編碼)即key-value coding ,一個非正式的協(xié)議蟋滴,使用字符串(鍵)訪問一個對象實例變量的機制染厅。而不是通過調(diào)用setter getter 方法存取方式去訪問。 運用了isa-swizzling技術(shù)津函,isa-swizzling就是類型混合指針機制肖粮。
SEL數(shù)據(jù)類型:它是編譯器運行Objective-C里的方法的環(huán)境參數(shù)。
IMP數(shù)據(jù)類型:它其實就是一個編譯器內(nèi)部實現(xiàn)時候的函數(shù)指針尔苦。當Objective-C編譯器去處理實現(xiàn)一個方法的時候涩馆,就會指向一個IMP對象,這個對象是C語言表達的類型
KVC內(nèi)部實現(xiàn):(1)首先根據(jù)方法名找到運行方法的時候所需要的環(huán)境參數(shù)蕉堰。 (2)它會自己isa指針介乎環(huán)境參數(shù)凌净,找到具體的方法實現(xiàn)的接口。(3)再直接查找得來的具體的方法實現(xiàn)
KVO(鍵值監(jiān)聽)屋讶,即Key-Value Observing冰寻,它提供一種機制,當指定的對象的屬性被修改后,對象就會接受到通知,前提是執(zhí)行了setter方法皿渗、或者使用了KVC賦值斩芭。kvo是基于kvc實現(xiàn)的
2.和notification(通知)的區(qū)別轻腺?
notification比KVO多了發(fā)送通知的一步。
兩者都是一對多划乖,但是對象之間直接的交互贬养,notification明顯得多,需要notificationCenter來做為中間交互琴庵。而KVO如我們介紹的误算,設(shè)置觀察者->處理屬性變化,至于中間通知這一環(huán)迷殿,則隱秘多了儿礼,只留一句“交由系統(tǒng)通知”,具體的可參照以上實現(xiàn)過程的剖析庆寺。
3.與delegate的不同蚊夫?
和delegate一樣,KVO和NSNotification的作用都是類與類之間的通信懦尝。但是與delegate不同的是:
這兩個都是負責發(fā)送接收通知知纷,剩下的事情由系統(tǒng)處理,所以不用返回值陵霉;而delegate 則需要通信的對象通過變量(代理)聯(lián)系琅轧;
delegate一般是一對一,而這兩個可以一對多撩匕。
鏈接:http://blog.csdn.net/chy305chy/article/details/51793373 ? http://www.reibang.com/p/e59bb8f59302 ? ? ?http://www.reibang.com/p/37a92141077e