iOS中KVC理解和應(yīng)用

概述:

KVC簡稱KeyValueCoding,是一個基于NSKeyValueCoding非正式協(xié)議的機(jī)制,可以允許開發(fā)者通過Key名直接訪問對象的屬性,或者給對象的屬性賦值。而不需要調(diào)用明確的存取方法。這樣就可以在運(yùn)行時(shí)動態(tài)訪問和修改對象的屬性。而不是在編譯時(shí)確定,這也是iOS開發(fā)中的黑魔法之一。很多高級的iOS開發(fā)技巧都是基于KVC實(shí)現(xiàn)的。

注:NSObject是定義了KVC的,所以繼承NSObject的對象都支持KVC,基本上所有的OC對象都支持KVC。

賦值過程:

MyObject *obj = [[MyObject alloc] init];

[obj setValue:@"哈哈哈" forKey:@"name"];

先查找相關(guān)的賦值方法,查找順序是:

????????set<Key>

? ? ? ? _set<Key>

? ? ? ?setIs<Key>

如果沒有找到相關(guān)賦值方法則調(diào)用+(BOOL)accessInstanceVariablesDirectly方法, 判斷是否可以直接訪問成員變量。(系統(tǒng)默認(rèn)是返回YES的,但可以重寫)

返回NO:調(diào)用- (void)setValue:(id)value forUndefinedKey:(NSString *)key方法并崩潰。錯誤異常是NSUnknownKeyException。

如果返回YES: 繼續(xù)找相關(guān)變量,查找順序是:

????????_<key>

????????_is<Key>

????????key

????????is<Key>

如果賦值方法和成員變量都不存在,則調(diào)用- (void)setValue:(id)value forUndefinedKey:(NSString *)key?并拋出異常NSUnknownKeyException。

取值過程:

MyObject *obj = [[MyObject alloc] init];

NSLog(@"%@",[obj valueForKey:@"name”]);

先查找相關(guān)賦值方法,查找順序是:

????????get<Key>

????????key

如果沒有找到相關(guān)方法,則調(diào)用+ (BOOL)accessInstanceVariablesDirectly?判斷是否可以直接訪問成員變量。

如果返回NO,則調(diào)用valueForUndefinedKey:, 并拋出系統(tǒng)異常:NSUnknownKeyException。

如果返回YES,則繼續(xù)查找相關(guān)變量,查找順序是

????????_<key>

????????_is<Key>

????????<key>

? ? ? ? is<Key>

如果取值方法或者成員變量都不存在,則調(diào)用valueForUndefinedKey:方法,并拋出異常:NSUnknownKeyException。

注:如果想禁用KVC,重寫+ (BOOL)accessInstanceVariablesDirectly 方法讓其返回NO即可,這樣 如果KVC找不到set<Key>屬性名時(shí),則會直接調(diào)用- (void)setValue:(id)value forUndefinedKey:(NSString *)key?并拋出異常NSUnknownKeyException。

常用場景:

1、屬性賦值

Boy *jack = [[Boy alloc] init];

jack.book = [[Book alloc] init];

[jack.book setValue:@"iOS"forKeyPath:@"name"];//方式一

[jack setValue:@"C++"forKeyPath:@"book.name"];//方式二

2、添加私有成員變量

[jack setValue:@"182" forKeyPath:@"_height"];

3、KVC可以修改類的私有變量

可以看出利用KVC可以修改類的私有變量,可以修改IOS隱藏一些屬性,如UITextField的placeHolderText默認(rèn)style在需求中達(dá)不到要求,我們可以直接通過KVC快速定義自己的style,代碼如下:

[textField setValue:[UIColor redColor] forKeyPath:@"placeholderLabel.textColor"];

4、KVC可以用來給model賦值

NSDictionary*dic = @{@"name":@"book",@"num":@"66"};? ??

GoodModel *model = [[GoodModel alloc] init];

[model setValuesForKeysWithDictionary:dic];

NSLog(@"model.name : %@",model.name);

NSLog(@"model.num : %@",model.num);

注意:如果 model 屬性和 dic 不匹配會怎樣?

第一種情況,model多一個屬性:這樣程序沒問題,model多出的屬性會是nil

第二種情況,model少一個屬性:程序會崩潰

第三種情況,model的屬性名字和dic的key不匹配 : 程序會崩潰

解決方法:?第二種和第三種崩潰的解決辦法是重寫方法 ?-(void)setValue:(id)value forUndefinedKey:(NSString *)key

- (void)setValue:(id)value forUndefinedKey:(NSString*)key{

? ? ? ? ? ? ? ?if([key isEqualToString:@"id"]){

? ? ? ? ? ? ? ? ? ? ? ? ? self.goodId = (NSString*)value;

? ? ? ? ? ? ? ? ? }

? ? }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • KVC定義 KVC(Key-value coding)鍵值編碼,就是指iOS的開發(fā)中,可以允許開發(fā)者通過Key名直...
    葉子絲閱讀 680評論 0 1
  • 1. KVO 一.KVO原理的使用與證明 我們在開發(fā)的過程中經(jīng)常使用KVO和KVC,但是我們并不了解其底層原理和功...
    周灬閱讀 917評論 0 9
  • 【原創(chuàng)博文,轉(zhuǎn)載請注明出處!】之前做iOS開發(fā)的時(shí)候經(jīng)常使用KVO來監(jiān)聽對象屬性值的變化去執(zhí)行一些操作,但是從未思...
    RephontilZhou閱讀 1,161評論 1 9
  • KVC定義 KVC(Key-value coding)鍵值編碼,就是指iOS的開發(fā)中,可以允許開發(fā)者通過Key名直...
    SheIsMySin_72e7閱讀 421評論 0 0
  • KVC KVC定義 KVC(Key-value coding)鍵值編碼,就是指iOS的開發(fā)中,可以允許開發(fā)者通過K...
    暮年古稀ZC閱讀 2,288評論 2 9

友情鏈接更多精彩內(nèi)容