IOS KVC 鍵值編碼 模式

2021-07-09 23:20:28 字數 3054 閱讀 8509

在ios的中,沒有絕對的私有,包括方法和變數。私有方法通過類例項無法直接訪問,但因為有"編譯時執行"機制,我們可以通過類似perfromselectoe的方法來訪問私有方法。而ios中的私有變數通過所謂的kvc模式也是可以訪問的。下面特酷吧整理了ios kvc模式的使用方法。

kvc模式就是key-value coding(鍵值編碼),它的原理是使用字串標識,間接訪問物件屬性。關鍵方法在nskeyvaluecodingprotocol中定義。kvc支援類物件和內建基本資料型別。我們主要使用到它的兩對方法:

1,setvalue:forkey,valueforkey;傳入nsstring屬性的名字

2,setvalue:forkeypath,valueforkeypath(傳入nsstring屬性的路徑,xx.xx形式)

需要注意:

當通過kvc呼叫物件時,比如:[self valueforkey:@"tekuba"];

程式會自動試圖通過幾種不同的方式解析這個呼叫。首先查詢物件是否帶有tekuba這個方法以及gettekuba,_tekuba以及_gettekuba這幾種形式,如果沒找到,會繼續查詢物件是否帶有tekuba這個例項變數(ivar),如果還沒有找到,程式會繼續試圖呼叫 -(id) valueforundefinedkey:這個方法。如果這個方法還是沒有被實現的話,程式會丟擲乙個nsundefinedkeyexception異常錯誤(待確認)。

設計valueforundefinedkey:方法的主要目的是當你使用-(id)valueforkey方法從物件中請求值時,物件能夠在錯誤發生前,有最後的機會響應這個請求

請看下面的示例:

標頭檔案tekubanet.h

#import@inte***ce tekubanet:nsobject

@end

實現檔案

#import"tekubanet.h"

@implementation tekubanet

@end

這個tekubanet類很簡單,只有乙個url變數。這種情況我們是沒有辦法通過tekubanet的類例項訪問url的。

下面我們使用kvc模式訪問url。如下:

int main (int argc, const char * argv)
下面我們對**做一些補充:

定義乙個webmaster類,特酷吧的博主:

標頭檔案webmaster.h

#import@inte***ce webmaster:nsobject

@end

實現檔案

#import"webmaster.h"

@implementation webmaster

@end

將webmaster新增到tekubanet類,如下:

#import@inte***ce tekubanet:nsobject

@end

tekubanet的實現檔案不變。

下面演示使用kvc模式訪問tekubanet中webmaster的name屬性。

int main (int argc, const char * argv)
另外需要注意,kvc還有乙個重要的特點就是自動裝箱拆箱功能:即kvc會根據字串自動的轉型成適當的資料型別,例如:

@inte***ce tekubanet:nsobject

則我們還是可以通過之前的方式訪問:

[tekubanet setvalue:@"365" forkey:@"runday"]; 

nslog(@"tekubanet runtime is %@",[tekubanet valueforkey:@"runday"]);

雖然runday是int型的,但我們一樣可以通過%@列印。

(1)setvalue:forkey的搜尋方式:

首先搜尋set:方法。如果成員用@property,@synthsize處理,因為@synthsize告訴編譯器自動生成set:格式的setter方法,所以這種情況下會直接搜尋到。注意:這裡的是指成員名,而且首字母大寫。下同。

上面的setter方法沒有找到,如果類方法accessinstancevariablesdirectly返回yes(注:這是nskeyvaluecodingcatogery中實現的類方法,預設實現為返回yes)。那麼按_,_is,,is的順序搜尋成員名。

如果找到設定成員的值,如果沒有呼叫setvalue:forundefinedkey:。

(2)valueforkey:的搜尋方式:

1. 首先按get、、is的順序查詢getter方法,找到直接呼叫。如果是bool、int等內建值型別,會做nsnumber的轉換。

2. 上面的getter沒有找到,查詢countof、objectinatindex:、atindexes格式的方法。

如果countof和另外兩個方法中的乙個找到,那麼就會返回乙個可以響應nsarray所有方法的**集合(collection proxy object)。傳送給這個**集合(collection proxy object)的nsarray訊息方法,就會以countof、objectinatindex:、atindexes這幾個方法組合的形式呼叫。還有乙個可選的get:range:方法。

3. 還沒查到,那麼查詢countof、enumeratorof、memberof:格式的方法。

如果這三個方法都找到,那麼就返回乙個可以響應nsset所有方法的**集合(collection proxy object)。傳送給這個**集合(collection proxy object)的nsset訊息方法,就會以countof、enumeratorof、memberof:組合的形式呼叫。

4. 還是沒查到,那麼如果類方法accessinstancevariablesdirectly返回yes,那麼按_,_is,,is的順序直接搜尋成員名。

5. 再沒查到,呼叫valueforundefinedkey:。

來自特酷吧

www.tekuba.net/program/294/

KeyValueCoding 鍵值編碼

void btnclick uibutton btn if btn.tag 100 修改 teacher 的變數 else 修改 student 的變數 sm setvalue xiaoxin forkey name 給成員變數賦值 void setvalues sm studentmodel al...

鍵值編碼KVC

許多程式設計技術都基於間接機制,包括整個物件導向程式設計領域。本章將介紹另一種間接機制,這種機制不屬於obj c語言的特性,而是cocoa提供的一種特性。我們知道在c 中可以通過反射讀寫乙個物件的屬性,有時候這種方式特別方便,因為你可以利用字串的方式去動態控制乙個物件。其實由於objc的語言特性,你...

Oc KVC 鍵值編碼

是一種間接地訪問物件例項變數的機制 通過setvalue forkey 間接地為物件的例項變數做賦值 通過valueforkey 間接地取到物件的例項變數 首先定義兩個類person類 和phone類 1.先檢查有沒有name這個例項變數 2.如果沒有,會檢查同名的帶 的例項變數 3.如果還沒有,會...