KVC:Key Value Coding,取其三個單詞首字母濃縮而成。直白翻譯過來就是鍵值編碼,什麼意思呢?簡單來講,就是操做一個對象,也能夠像操做字典同樣,經過key來取值和賦值。
網絡
咱們先建立一個HMPerson類來試驗一下。框架
而後實例化HMPerson類的對象,此時,咱們若是想要給它的name和age兩個屬性賦值和取值,就能夠用點語法來操做,如圖:編碼
可是,這種點語法方式顯得着實太low,接下來咱們就用比較高大上的方式——KVC的方式來賦值和取值。
咱們先簡單看看KVC裏的幾個方法:
賦值:翻譯
- (void)setValue:(nullable id)value forKey:(NSString *)key; - (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
解釋:這種方式比較暴力,後頭會解釋3d
-(void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id>*)keyedValues;
取值:對象
- (nullableid)valueForKey:(NSString *)key; - (nullable id)valueForKeyPath:(NSString *)keyPath;
KVC
**的優勢合集blog
優勢一:破門而入:與別人家的「私人專屬」親密接觸**
咱們都知道,若是@property寫在.h文件中,表明外界能夠經過調用對應的setter和getter方法(或點語法)來訪問對應的私有成員變量,但若是寫在.m中,表明只容許本類中訪問,其餘地方訪問不了。所以,咱們給以前的Person類在.m文件中寫一個延展,把.h文件的@property挪到.m的延展中。而且在.m文件中再加一個用@private修飾的成員變量
如圖:繼承
對,僅需調用setValuesForKeysWithDictionary方法,傳入字典便可。這個方法內部,幫咱們作了咱們剛剛循環字典的操做,所以僅僅這一個方法就可完成字典數據轉模型數據,今後,媽媽不再用擔憂我寫多餘代碼了!字符串
KVC
**疑問解密get
疑問解密
1:
**
使用KVC是直接對成員變量賦值,仍是調用了這個成員變量對應的setter和getter方法呢?
爲了解決這個疑問,咱們給HMPerson類里加一個私有的成員變量name,而且給它寫好對應的getter和setter方法,如圖:
經過觀察,咱們發現用KVC來賦值時,對應的setter方法能被調用,用KVC來取值時,對應的getter方法也能被調用。
所以小夥伴們不用擔憂KVC會破壞本身已經寫好的屬性封裝規則。
疑問解密1小分支:
若是沒有getter方法和setter方法時,KVC是怎麼找成員變量的呢?
爲了弄清這個問題,咱們刪掉name的getter和setter方法。而後經過KVC方式賦值取值,會發現,依然能夠賦值和取值成功。而且是給p對象的成員變量_name賦值的。如圖:
此時發現,用KVC賦值的就是這個不帶下劃線的成員變量(即name)了。
所以,咱們能夠總結出,KVC賦值和取值的一套順序:
**
setValue:屬性值 forKeyPath:屬性路徑 valueForKeyPath:屬性名
複製代碼
後面帶Path的跟以前咱們用的KVC有什麼不一樣呢?咱們來研究研究!
假設此時有一個Dog類,而Person類裏也有個屬性是Dog類型的,叫pet,如圖
所以,也就是說,若是須要操做訪問一些「屬性裏的屬性」時,就用帶Path的方法來操做。
** 疑問解密
3:
**
若是用
KVC賦值時,某一個
Key,類中沒有會怎樣?
例如:咱們的
HMPerson類如今沒有
salary屬性。
此時,不管你輸錯多少次HMPerson對象不存在的屬性時,都不會在運行時讓程序崩潰,達到報錯「友好」的目的。
**總結
**
KVC是一套方便咱們用字符串來操做對象的機制,可使得操做對象時跟操做字典同樣的靈活。在字典轉模型的領域中應用起來極爲方便,而且
KVC能夠輕鬆的幫咱們突破訪問限制的一些問題,直接訪問到私有成員。