熟悉oc文法的同學也許都會懂得這麼一點:在oc中,類的成員變量或是方法是沒有絕對私有的。
私有方法直接通過類執行個體無法通路,但可 以借助oc的“編譯運作時”機制,也即“瞎子摸黑”機制(個人了解:隻要确定了該類有方法A,管你是私有共有,我用performSelector函數就 能調用你),說到這,也許有同學會自然想起,那私有變量如何去通路呢?貌似以前還真沒這樣搞過,然而現實是可以的,隻不過一般我們把變量設為類的私有變量 後是不希望自己或是其他人再去通路的,不然我隻能說你自己又在找賤了。。。。。。。。。。。。。。
好吧,言歸正傳,這篇文章主要是想介紹下oc中的KVC、KVO、KVB的實作機制,當然跟我上面說的那些肯定是有關系的啦。。
它 是一種使用字元串辨別符,間接通路對象屬性的機制,它是很多技術的基礎。主要的方法就兩對方法: (setValue:forKey,valueForKey)、setValue:forKeyPath,valueForKeyPath);這個東西有 什麼作用呢,我先不說原理,先說怎麼用,例子如下:
其實上面說的那兩對方法使用上基本是一樣的,隻是valueForKeyPath的值是一個路徑(路徑之間以點号 . 分割),比如資料成員就是對象自己,尋值過程就會向下深入下去。
注意,這裡的資料成員的名字都是使用的字元串的形式。這種使用方法的最好的用處在于将資料(名字)綁定到一些觸發器(尤其是方法調用)上,
例如鍵值對觀察(Key-Value Observing, KVO)等。
上 述代碼說明了類的成員變量也可以使用基類NSObject的那兩對方法去通路,不一定直接通過類執行個體通路,但是這種方式還是有一定的風險,具體危險情況請 參考這個:http://www.devbean.info/2011/04/from_cpp_to_objc_20/
然後我再說下原理,是俺Copy過來的,大家觀賞下:
KVC運用了一個isa- swizzling技術。isa-swizzling就是類型混合指針機制。KVC主要通過isa- swizzling,來實作其内部查找定位的。
isa指針,如其名稱所指,(就是is a kind of的意思),指向維護分發表的對象的類。該分發表實際上包含了指向實作類中的方法的指針,和其它資料。
比如說如下的一行KVC的代碼:
[site setValue:@"sitename" forKey:@"name"];
就會被編譯器處理成:
SEL sel = sel_get_uid ("setValue:forKey:");
IMP method = objc_msg_lookup (site->isa,sel);
method(site, sel, @"sitename", @"name");
首先介紹兩個基本概念:
(1)SEL資料類型:它是編譯器運作Objective-C裡的方法的環境參數。
(2)IMP資料 類型:他其實就是一個 編譯器内部實作時候的函數指針。當Objective-C編譯器去處理實作一個方法的時候,就會指向一個IMP對象,這個對象是C語言表述的類型(事實 上,在Objective-C的編譯器處理的時候,基本上都是C語言的)。
這下KVC内部的實作就很清楚的清楚了:一個對象在調用setValue的時候,
(1)首先根據方法名找到運作方法的時候所需要的環境參 數。
(2)他會從自己isa指針結合環境參數,找到具體的方法實作的接口。
(3)再直接查找得來的具體的方法實作。
這兩個機制是結合起來使用的,分别說下,
Key-Value Observing (簡寫為KVO):當指定的對象的屬性被修改了,允許對象接受到通知的機制。每次指定的被觀察對象的屬性被修改的時候,KVO都會自動的去通知相應的觀察 者。
KVO的優點
當 有屬性改變,KVO會提 供自動的消息通知。這樣的架構有很多好處。首先,開發人員不需要自己去實作這樣的方案:每次屬性改變了就發送消息通知。這 是KVO機制提供的最大的優點。因為這個方案已經被明确定義,獲得架構級支援,可以友善地采用。開發人員不需要添加任何代碼,不需要設計自己的觀察者模 型,直接可以在工程裡使用。其次,KVO的架構非常的強大,可以很容易的支援多個觀察者觀察同一個屬性,以及相關的值。
KVB實作的兩個基本方法
1:為對象添加觀察者OBserver addObserver:forKeyPath:options:context:
2:觀察者OBserver收到資訊的處理函數 observeValueForKeyPath:ofObject:change:context:
KVO和KVB最明顯的使用場景就是在一些界面實時顯示行很強的地方,比如股票走向、售票餘額等,這種方式免去了我們自己操作通知的麻煩,想到這,我發現當初點金和91市場中下載下傳頁面進度的顯示也完全可以采用這種方式。
先說到這兒吧,更精彩的待續。。。。。。。。
網絡上志同道合,我們一起學習網絡安全,一起進步,QQ群:694839022