轉自http://www.cnblogs.com/hibernate6/archive/2012/04/12/2521894.html
KVC運用了一個isa-swizzling技術。isa-swizzling就是類型混合指針機制。KVC主要通過isa- swizzling,來實現其內部查找定位的。isa指針,如其名稱所指,(就是is a kind of的意思),指向維護分發表的對象的類。該分發表實際上包含了指向實現類中的方法的指針,和其它數據。
比如說如下的一行KVC的代碼:
[site setValue:@"sitename" forKey:@"name"];
首先介紹兩個基本概念:
(1)SEL數據類型:它是編譯器運行Objective-C裏的方法的環境參數。
(2)IMP數據類型:他其實就是一個 編譯器內部實現時候的函數指針。當Objective-C編譯器去處理實現一個方法的時候,就會指向一個IMP對象,這個對象是C語言表述的類型(事實 上,在Objective-C的編譯器處理的時候,基本上都是C語言的)。
這下KVC內部的實現就很清楚的清楚了:一個對象在調用setValue的時候,(1)首先根據方法名找到運行方法的時候所需要的環境參 數。(2)他會從自己isa指針結合環境參數,找到具體的方法實現的接口。(3)再直接查找得來的具體的方法實現。Key-Value Observing機制的概述
Key-Value Observing (簡寫爲KVO):當指定的對象的屬性被修改了,允許對象接受到通知的機制。每次指定的被觀察對象的屬性被修改的時候,KVO都會自動的去通知相應的觀察 者。
KVO的優點
當有屬性改變,KVO會提供自動的消息通知。這樣的架構有很多好處。首先,開發人員不需要自己去實現這樣的方案:每次屬性改變了就發送消息通知。這 是KVO機制提供的最大的優點。因爲這個方案已經被明確定義,獲得框架級支持,可以方便地採用。開發人員不需要添加任何代碼,不需要設計自己的觀察者模 型,直接可以在工程裏使用。其次,KVO的架構非常的強大,可以很容易的支持多個觀察者觀察同一個屬性,以及相關的值。
KVB
兩個基本方法
1:爲對象添加觀察者OBserver
addObserver:forKeyPath:options:context:
2:觀察者OBserver收到信息的處理函數
observeValueForKeyPath:ofObject:change:context:
MVC架構是"Model-View-Controller"的縮寫,中文翻譯爲"模式-視圖-控制器"。MVC應用程序總是由這三個部分組成。 Event(事件)導致Controller改變Model或View,或者同時改變兩者。只要Controller改變了Models的數據或者屬性, 所有依賴的View都會自動更新。類似的,只要Controller改變了View,View會從潛在的Model中獲取數據來刷新自己。
MVC架構最早是smalltalk語言研究團提出的,應用於用戶交互應用程序中。
MVC模式是一個複雜的架構模式,其實現也顯得非常複雜。但是,我們已經總結出了很多可靠的設計模式,多種設計模式結合在一起,使MVC模式的 實現變得相對簡單易行。Views可以看作一棵樹,顯然可以用Composite Pattern來實現。Views和Models之間的關係可以用Observer Pattern體現。Controller控制Views的顯示,可以用Strategy Pattern實現。Model通常是一個調停者,可採用Mediator Pattern來實現。
KVC--KVO--KVB優勢
些機制通過規定了一組通用的Cocoa命名法則、調用規則等,實現瞭如下功能:
在很多時候接觸到很多地方都有對KVC,KVO的描述,但是都是一筆帶過.只知道這是Object-C提供的一個不錯的機制,可以很好的減少澆水代碼。
其實KVC、KVO即NSKeyValueCoding和NSKeyValueCoding的簡稱。
那我們KVO、KVC用來做什麼的我們又怎麼使用它呢?
首先我們先了解下KVO的機制
KVO:當指定的對象的屬性被修改了,允許對象接收到通知的機制。每當在類中定義一個監聽
如:
[self addObserver:self
forKeyPath:@"items"
options:0
context:contexStr];
***
當然你還可以監聽其他對象的屬性變化
[person addObserver:money
forKeyPath:@"account"
options:0
context:contexStr];
****
只要當前類中items這個屬性發生的變化都會觸發到以下的方法。
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
KVO的優點:
當有屬性改變,KVO會提供自動的消息通知。這樣開發人員不需要自己去實現這樣的方案:每次屬性改變了就發送消息通知。
這是KVO機制提供的最大的優點。因爲這個方案已經被明確定義,獲得框架級支持,可以方便地採用。
開發人員不需要添加任何代碼,不需要設計自己的觀察者模型,直接可以在工程裏使用。
其次,KVO的架構非常的強大,可以很容易的支持多個觀察者觀察同 一個屬性,以及相關的值。
KVC的實現分析
KVC運用了一個isa-swizzling技術。
isa-swizzling就是類型混合指針機制。KVC主要通過isa-swizzling,來實現其內部查找定位的。
isa指針,就是is a kind of的意思,指向維護分發表的對象的類。該分發表實際上包含了指向實現類中的方法的指針,和其它數據。
如下KVC的代碼:
[person setValue:@"personName" forKey:@"name"];
就會被編譯器處理成:
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (person->isa,sel);
method(person, sel, @"personName", @"name");
***
其中:
SEL數據類型:它是編譯器運行Objective-C裏的方法的環境參數。
IMP數據類型:他其實就是一個 編譯器內部實現時候的函數指針。當Objective-C編譯器去處理實現一個方法的時候,就會指向一個IMP對象,這個對象是C語言表述的類型。
***
KVC在調用方法setValue的時候
(1)首先根據方法名找到運行方法的時候所需要的環境參數。
(2)他會從自己isa指針結合環境參數,找到具體的方法實現的接口。
(3)再直接查找得來的具體的方法實現。
這樣的話前面介紹的KVO實現就好理解了
當一個對象註冊了一個觀察者,被觀察對象的isa指針被修改的時候,isa指針就會指向一箇中間類,而不是真實的類。
所以isa指針其實不需要指向實例對象真實的類。所以我們的程序最好不要依賴於isa指針。在調用類的方法的時候,最好要明確對象實例的類名。
這樣只有當我們調用KVC去訪問key值的時候KVO纔會起作用。所以肯定確定的是,KVO是基於KVC實現的。