Objective C之KVC 鍵值編碼

2021-07-11 04:56:55 字數 3707 閱讀 5809

ios中key-value coding (kvc)俗稱鍵值編碼,是乙個非正式的協議,它提供一種機制來間接訪問物件的屬性。

直接訪問物件是通過呼叫訪問器的方法實現,而kvc不需要呼叫訪問器的設定和獲取方法,可以直接訪問物件的屬性。   

kvc的操作方法由nskeyvaluecoding協議提供,而nsobject就實現了這個協議,也就是說objc中幾乎所有的物件都支援kvc操作,

常用的kvc操作方法如下:

1)對屬性賦值(動態設定): 

setvalue:屬性值 frkey:屬性名(用於簡單路徑);

setvalue:屬性值 forkeypath:屬性路徑(用於復合路徑,例如person有乙個account型別的屬性,那麼person.account就是乙個復合屬性);

kvc的一般用法:

setvalue:屬性值 forkey:屬性名和valueforkey:屬性名

- (void)viewdidload 

#pragma mark --setvalue:屬性值 forkey:屬性名

-(void)test1

輸出結果:

2)對屬性取值(動態讀取):

valueforkey:屬性名 (用於簡單路徑);

valueforkeypath:屬性名(用於復合路徑);

setvalue:屬性值 forkeypath:屬性路徑和valueforkeypath:屬性名(用於復合路徑)

- (void)viewdidload 

#pragma mark --setvalue:屬性值 forkeypath:屬性路徑和valueforkeypath:屬性名(用於復合路徑)

-(void)test2

輸出結果:

注意:(1). key的值必須正確,如果拼寫錯誤,會出現異常

1> * 首先去接收者(呼叫方法的那個物件)的類中查詢與key相匹配的訪問器方法(-set),如果找到了乙個方法,就檢查它引數的型別,如果它的引數型別不是乙個物件指標型別,但是只為nil,就會執行setnilvalueforkey:方法,setnilvalueforkey:方法的預設實現,是產生乙個nsinvalidargumentexception的異常,但是你可以重寫這個方法.

* 如果方法引數的類是乙個物件指標型別,就會簡單的執行這個方法,傳入對應的引數.如果方法的引數型別是nsnumbernsvalue的對應的基本型別,先把它轉換為基本資料類,再執行方法,傳入轉換後的資料.

2> * 如果沒有對應的訪問器方法(setter方法),如果接受者的類的+accessinstancevariablesdirectly方法返回yes,那麼就查詢這個接受者的與key相匹配的例項變數(匹配模式為_,_is,,is):比如:key為age,只要屬性存在_age,_isage,age,isage中的其中乙個就認為匹配上了,如果找到這樣的乙個例項變數,並且的型別是乙個物件指標型別,

3> * 首先released物件上的舊值,然後把傳入的新值retain後的傳入的值賦值該成員變數,如果方法的引數型別是nsnumber或nsvalue的對應的基本型別,先把它轉換為基本資料類,再執行方法,傳入轉換後的資料.

* 如果訪問器方法和例項變數都沒有找到,執行setvalue:forundefinedkey:方法,該方法的預設實現是產生乙個nsundefinedkeyexception型別的異常,但是我們可以重寫setvalue:forundefinedkey:方法

(2). 當key的值是沒有定義的,valueforundefinedkey:這個方法會被呼叫,如果你自己寫了這個方法,key的值出錯就會呼叫到這裡來

(3). 因為類key反覆巢狀,所以有個keypath的概念,keypath就是用.號來把乙個乙個key鏈結起來,這樣就可以根據這個路徑訪問下去

(4).nsarraynsset等都支援kvc

3)key值找不到時,異常處理

使用kvc時,如果**中的key值不存在,會丟擲異常,可以在類中通過重寫它提供

- (void)setvalue:(id)value forundefinedkey:(nsstring *)key
當key不存在時,會自動呼叫上面的這個方法,可以在這個方法中進行處理

- (void)setvalue:(id)value forundefinedkey:(nsstring *)key
4)kvc的字典轉模型和模型轉字典

1>字典轉模型

當我們需要把json字串反序列化成我們想要的物件 ,可以通過下面的方法

- (void)setvaluesforkeyswithdictionary:(nsdictionary*)keyedvalues

- (id)initwithdictionary:(nsdictionary *)dictionary 

return self;

}

注意:字典中的key 和物件屬性要求一樣

2>模型轉字典

- (nsdictionary *)dictionarywithvaluesforkeys:(nsarray *)keys;

nsdictionary *dic = [self.dataarray dictionarywithvaluesforkeys:@[@"name",@"age"]];

for (int i =0 ; i5)總結

1)kvc需要把字串屬性名稱轉換後才能賦值,呼叫的set方法,效能消耗較高

2)kvc查詢乙個屬性進行讀取的一般順序

1>動態設定屬性,

優先考慮呼叫seta方法,如果沒有該方法則優先考慮搜尋成員變數_a,如果仍然不存在則搜尋成員變數a,如果最後仍然沒搜尋到則會呼叫這個類的setvalue:forundefinedkey:方法(注意搜尋過程中不管這些方法、成員變數是私有的還是公共的都能正確設定);

2>動態讀取屬性

優先考慮呼叫a方法(屬性a的getter方法),如果沒有搜尋到則會優先搜尋成員變數_a,如果仍然不存在則搜尋成員變數a,如果最後仍然沒搜尋到則會呼叫這個類的valueforundefinedkey:方法(注意搜尋過程中不管這些方法、成員變數是私有的還是公共的都能正確讀取);

3>解析的資料 型別不確定處理

-(void)setvalue:(id)value forkey:(nsstring *)keyelse

}

別忘加上這個,也要重寫(未被定義的不做處理):

-(void)setvalue:(id)value forundefinedkey:(nsstring *)key

iOS開發之UI基礎 KVC

k vc key value coding 1.字典轉模型 dic answer dic icon dic title dic options kvc 把字典中的值,賦給當前物件制定的屬性 answer self setvalue dic answer forkeypath answer 遍歷字典中...

Objective C語法之Category的使用

無論乙個類設計的如何完美,都不可避免的會遇到沒有 到的需求,那怎麼擴充套件現有的類呢?當然,繼承是個不錯的選擇。但是objective c提供了一種特別的方式來擴充套件類,叫catagory,可以動態的為已經存在的類新增新的行為。這樣可以保證類的原原來的基礎上,較小的改動就可以增加需要的功能。使用c...

Objective C語法之Category的使用

無論乙個類設計的如何完美,都不可避免的會遇到沒有 到的需求,那怎麼擴充套件現有的類呢?當然,繼承是個不錯的選擇。但是objective c提供了一種特別的方式來擴充套件類,叫catagory,可以動態的為已經存在的類新增新的行為。這樣可以保證類的原原來的基礎上,較小的改動就可以增加需要的功能。使用c...