iOS知識梳理11:KVC 和KVO

參考鏈接:
[精辟]KVO 和 KVC 的區(qū)別和用法,干貨?。。?/a>
iOS開發(fā)技巧系列---詳解KVC
KVC的優(yōu)點和缺點

KVC

KVC是鍵值編碼(key-value coding),cocoa的標(biāo)準(zhǔn)組成部分, 是一種可以直接通過字符串的名字(Key)來訪問類屬性的機制,而不是通過直接調(diào)用setter,getter方法來訪問.

KVC的具體用法

1.訪問類的私有變量
無論類中的成員是否私有,用KVC都可以強行"破門而入",對他正常的取值和賦值.
比如一個Dog類

@interface Dog : NSObject
{
    @private
    double height;
}

可以通過setValue:forKey:方法來給私有變量賦值(這里關(guān)鍵字Key就是height字符串)

[dog setValue:@12 forKey:@"height"];

可以通過valueForKey:方法來讀取私有變量的值.

[dog valueForKey:@"height"];

如果屬性本身是一個類.
比如

@property (nonatomic,strong) Dog *pet;

我們可以通過帶Path的方法來取到這個屬性.

[person setValue:@12 forKeyPath:@"pet.height"];

2.使用KVC將字典(或者說json)轉(zhuǎn)化為模型

NSDictionary *dic = @{
              @"name":@"jack"
              @"money":@"20.7"
}
//創(chuàng)建模型,假定模型已有兩個屬性name和money
Person *p = [p new];

//轉(zhuǎn)換類型
[p setValuesForKeysWithDictionary:dic];

NSLog(@"%@",p.name);

3.使用KVC直接訪問NSArray或者NSSet的屬性值

//把三本書存入books數(shù)組.
NSArray *books = @[book1,book2,book3];
//把書名取出來存到另一個數(shù)組中
NSArray *names = [books valueForKeyPath:@"name"];
//打印加個的平均值
NSLog(@"%@",[books valueForKeyPath:@"avg.price"]); 

KVO

詳情請看設(shè)計模式那一部分.

iOS知識梳理3:設(shè)計模式

KVO&KVC常見面試題

問題1:KVC的底層實現(xiàn)(或者,kvc的查找順序)

當(dāng)一個對象調(diào)用setValue方法時,方法內(nèi)部會做以下操作:

①..檢查是否存在相應(yīng)key的set方法,如果存在,就調(diào)用set方法
②...如果set方法不存在,就會查找與key相同名稱并且?guī)聞澗€的成員屬性,如果有,則直接給成員屬性賦值
③....如果沒有找到_key,就會查找相同名稱的屬性key,如果有就直接賦值
④.....如果還沒找到,則調(diào)用valueForUndefinedKey:和setValue:forUndefinedKey:方法。這些方法的默認(rèn)實現(xiàn)都是拋出異常,我們可以根據(jù)需要重寫它們。

問題2:KVO的底層實現(xiàn)
  • kvo基于runtime機制實現(xiàn)。

  • 使用了isa 混寫(isa-swizzling),當(dāng)一個對象(假設(shè)是person對象,person的類是MYPerson)的屬性值(假設(shè)person的age)發(fā)生改變時,系統(tǒng)會自動生成一個類,繼承自MYPerson :NSKVONotifying_MYPerson,在這個類的setAge方法里面,調(diào)用[super setAge:age] [self willChangeValueForKey:@"age"] 和 [self didChangeValueForKey:@"age"]
    ,而這兩個方法內(nèi)部會主動調(diào)用監(jiān)聽者內(nèi)部的 - (void)observeValueForKeyPath 這個方法。

  • 想要看到NSKVONotifying_MYPerson很簡單,在self.person.age = 20; 這里打斷點,在調(diào)試區(qū)域就能看到 _person->NSObject->isa=(Class)NSKVONotifying_MYPerson.同時我們在 self.person = [[MYPerson alloc]init];后面打斷點,看到_person->NSObject->isa=(Class)MYPerson,由此可見,在添加監(jiān)聽者之后,person類型已經(jīng)由MYPerson被改變成NSKVONotifying_MYPerson

問題3:什么是KVO和KVC?

答:KVC:鍵 – 值編碼 使用字符串直接訪問對象的屬性。
KVO:鍵值觀察機制,它提供了觀察某一屬性變化的方法

其他KVO&KVC相關(guān)面試補充連接

KVC&KVO面試題
可能碰到的iOS筆試面試題(7)--KVO-KVC

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

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

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