KVC KVO

KVC

kvc提供了一種在運行時而非編譯時動態(tài)訪問對象屬性與成員變量的方式,該方法不需要調(diào)用get/set方法

OC中訪問變量的方式

  1. _name 直接訪問
  2. self.name 利用屬性訪問
  3. [self setValue:@"" forKey:@""] KVC

[self valueForKey:@"someKey"];
查找過程:
1.查找對象是否帶有someKey這個方法
2.查找對象是否代用someKey這個實例變量(iVar)
3.調(diào)用 -(id)valueForUndefinedKey
4.拋出NSUndefinedKeyException異常

KVC內(nèi)部實現(xiàn)
一個對象在調(diào)用setValue時
1.根據(jù)方法名找到運行方法的時候所需要的環(huán)境參數(shù)
2.從自己的isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實現(xiàn)的接口,isa指針,指向維護分發(fā)表的對象的類,該分發(fā)表實際上包含了指向?qū)崿F(xiàn)類中的方法的指針
3.直接查找得來的具體的方法實現(xiàn)

@interface LBKVC : NSObject {
    NSString *firstName;
}

@property (nonatomic, strong) NSString *lastName;

@end
[_kvc setValue:@"dog" forKey:@"lastName"]; // 屬性 會觸發(fā) set 方法
[_kvc setValue:@"cat" forKey:@"firstName"]; // 成員變量 沒有set方法

KVO

KVO主要用來解耦
在上面介紹的KVC機制上加上KVO的自動觀察消息通知機制就水到渠成了。
*KVO是基于runtime機制實現(xiàn)的
*當某個類的屬性對象被觀察時,系統(tǒng)會在運行期動態(tài)地創(chuàng)建該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter方法。派生類在被重寫的setter方法內(nèi)實現(xiàn)真正的通知機制
*如果原來類為Person,那么生成的派生類名為NSKVONotifying_Person
*每個類對象中都有一個isa指針指向當前類,當一個類對象被觀察,那么系統(tǒng)會偷偷將isa指針指向動態(tài)生成的派生類,從而在給被監(jiān)控屬性賦值時執(zhí)行的是派生類的setter方法
*鍵值觀察通知 依賴于NSObject的兩個方法 willChangeValueForKey 和 didChangeValueForKey 。在一個被觀察屬性發(fā)生改變之前,willChangeValueForKey 一定會被調(diào)用,這樣就會記錄舊的值,而當值改變后,didChangeValueForKey 會被調(diào)用,繼而observeValueForKey:ofObject:change:context:也會被調(diào)用

kvo0.png

// 手動觸發(fā)

[self willChangeValueForKey:@"name"];
[self didChangeValueForKey:@"name"];

demo地址

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

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

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