一 KVC的基本概念 KVC是Key Value Coding的縮寫,意思是鍵值編碼。 在iOS中,提供了一種方法通過使用屬性的名稱(也就是Key)來間接訪問對象屬性的方法,這個方法可以不通過getter/setter方法來訪問對象的屬性。用KVC可以間接訪問對象屬性的機制。通常我們使用valueF ...
一 KVC的基本概念
KVC是Key Value Coding的縮寫,意思是鍵值編碼。
在iOS中,提供了一種方法通過使用屬性的名稱(也就是Key)來間接訪問對象屬性的方法,這個方法可以不通過getter/setter方法來訪問對象的屬性。
用KVC可以間接訪問對象屬性的機制。通常我們使用valueForKey 來替代getter 方法,setValue:forKey來代替setter方法。
—————————————————————————————————————————————————————————————
二 常用方法及特性
1)KVC的常用方法
- (id)valueForKey:(NSString *)key; ------根據key的值讀取對象的屬性
- (void)setValue:(id)value forKey:(NSString *)key; ------根據key的值來寫對象的屬性 setNilValueForKey: 當對非類對象屬性設置nil時,調用,預設拋出異常。 valueForUndefinedKey:------錯誤攔截,當key的值是沒有定義的,這個方法會被調用,如果你自己寫了這個方法,key的值出錯就會調用到這裡來
KVC 最常用的還是在序列化和反序列話對象。尤其是在json 轉模型的時候,KVC讓程式員擺脫了繁瑣無營養的代碼堆積。減少代碼量就是減少出錯的概率
2) 使用 KVC 為對象賦值或者取值時,需要知道準確的鍵值, 相比較點語法,KVC 是一種間接的傳遞方式,這種方式有利於
對象解耦,讓對象彼此之間的耦合度不會太高。
KVC 不但能夠賦值,而且還能破壞只讀的特性。OC中的KVC操作就和Java中使用反射機制去訪問類的private許可權的變數,很暴力,這樣做就會破壞類的封裝性. 類的私有屬性和只讀屬性都可以通過KVC去訪問.
當然這隻是我們需要註意的一個細節,更重要的是KVC 有自動裝箱(自動類型轉換)的功能,我們不需要去轉換類型了。
3)、支持鍵值路徑
什麼叫支持鍵值路徑?鍵值路徑是對於一個類中有數組對象的屬性進行便捷操作
說白了就是支持嵌套。因為類key反覆嵌套,所以有個keyPath的概念,keyPath就是用.號來把一個一個key鏈接起來,這樣就可以根據這個路徑訪問下去(KVC在按照鍵值路徑取值時,會自動層層深入,獲取對應的鍵值)
4)支持操作符
假如我們有10個字元串,我們想求出這10個字元串的總長度,我們可以使用KVC提供的操作符。
NSArray *books=@[@"鳥哥燒烤私房菜",@"程式員攤煎餅寶典",@"麻辣燙基礎教程"];
NSLog(@"%@",[books valueForKeyPath:@"@sum.length"]);
這裡的@sum 是KVC 提供的,不是我們寫的。像這樣的函數共有5個@avg,@count,@max,@min,@sum。我們直接用就可以了
5)KVC的缺點: 一旦使用 KVC 你的編譯器無法檢查出錯誤,即不會對設置的鍵、鍵路徑進行錯誤檢查,且執行效率要低於合成存取器方法和自定的 setter 和 getter 方法。因為使用 KVC 鍵值編碼,它必須先解析字元串,然後在設置或者訪問對象的實例變數。所以只有當你非常需要它提供的可擴展性時才使用它。 ————————————————————————————————————————————————————————————— 三 KVC機制通過key找到value的原理
-
當通過KVC調用對象時,比如:[self valueForKey:@”someKey”]時,程式會自動試圖通過下麵幾種不同的方式解析這個調用。
-
首 先查找對象是否帶有 someKey 這個方法,如果沒找到,會繼續查找對象是否帶有someKey這個實例變數(iVar),如果還沒有找到,程式會繼續試圖調用 -(id) valueForUndefinedKey:這個方法。如果這個方法還是沒有被實現的話,程式會拋出一個NSUndefinedKeyException 異常錯誤。
-
補充:KVC查找方法的時候,不僅僅會查找someKey這個方法,還會查找getsomeKey這個方 法, 前面加一個get,或者_someKey以_getsomeKey這幾種形式。同時,查找實例變數的時候也會不僅僅查找someKey這個變數,也會查找 _someKey這個變數是否存在。
-
設計valueForUndefinedKey:方法的主要目的是當你使用-(id)valueForKey方法從對象中請求值時,對象能夠在錯誤發生前,有最後的機會響應這個請求。