小碼哥-(知其所以然三)論觀察者模式之KVC和KVO

在開發的時候,是不是忽然有種錯覺:我們好像是代碼的搬運工,一個項目開始,把自己寫好的、封裝好的類、框架亦或別人寫好的第三方框架不假思索的運用到項目中,一方面:項目時間緊;二方面:簡單好用,減少了代碼量。但是有時候,我們是否應該停下腳步, 從底層去看看代碼的世界,那樣我們收益會頗豐,讓我們一起走在學習的路上吧!
在開發中,有很多地方都需要對KVC和KVO進行運用。我們只知道這是Object-C提供的一個不錯的機制,可以很好的減少代碼;但是我們可能不會過多的去了解它底層是如何實現的,下面,我們一起來看看吧!
(一) KVC的實現與運用


KVC 的底層實現是運用了 isa-swizzling 技術,也就是類型混合指針機制。通過 isa-swizzling,能夠來實現其內部查找定位的。isa 指針,就是 is a kind of 的意思,指向系統維護分發表的對象的類。該分發表實際上包含了指向實現類中的方法的指針和其它數據對象。


比如下面的這句代碼:


[Account  setValue:@"userAccount" forKey:@"account"];


經過KVC內部編譯後,其內部實現如下:


SEL sel = sel_get_uid("setValue:forKey:");
IMP method = objc_msg_lookup (account->isa,sel);
method(account,sel,@"userAccount",@"account");
我們就可以分析得出:
SEL是一種數據類型,是編譯器運行Objective-C裏的方法的環境參數。
IMP也是一種數據類型,說白了就是編譯器內部實現時候的函數指針。也就是說:當編譯器去處理實現一個方法的時候,就會指向一個IMP對象,這個對象是C語言表述的類型。  
KVC在調用方法setValue的時候,會依照以下步驟執行:
a)根據方法名找到運行方法的時候所需要的環境參數;
b) 結合isa指針,找到具體的方法實現的接口;
c) 對查找的方法進行具體的實現
所以,KVC的運作流程就是:當一個對象註冊了一個觀察者,被觀察對象的isa指針被修改的時候,isa指針就會指向一箇中間類,而不是真實的類。比如說:我們在運用KVC進行字典和模型之間轉化時,要完全一致對象實例的類名,就是這個道理。


(二)KVO的實現和運用
KVO是指當指定的對象的屬性被修改了,讓要進行事件處理的對象及時接收到通知的一種實現機制。


定義:
[self addObserver:self forKeyPath:@"code" options:0 context:str];
實現
- (void)observeValueForKeyPath:(NSString *)keyPath   ofObject:(id)object   change:(NSDictionary *)change  context:(void *)context
在運用KVO的時候,當有屬性發生改變時,會提供自動的消息通知。這樣我們在開發的時候就不需要去具體實現(運用代理、block),如每次屬性改變了就發送消息通知。我們不需要設計自己的觀察者模型,直接可以在項目裏進行使用,十分快捷和方便。
此外,KVO 的架構非常的強大,有框架支持,可以很容易的支持多個觀察者觀察同一個屬性,以及相關的值。
具體的實例會在稍後發表,讓我們在案例中進一步體會這兩種觀察者模式的運用和實現。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章