kvc kvo

原文?kvc kvo

KVC 概論

KVC(全稱 key-value-coding)即鍵值編碼。KVC 的操作方法由NSKeyValueCoding 非正式協議提供,而NSObject(NSKeyValueCoding)就實現了這個協議,也就是說ObjC中幾乎所有的對象都支持 KVC 操作,它是一種不通過存取方法(Setter、Getter),而通過屬性名稱字符串(key)間接訪問類屬性(實例變量)的機制。

- (void)setValue:(nullable id)value forKey:(NSString *)key;

- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;

- (id)valueForKey:(NSString *)key;

- (nullable id)valueForKeyPath:(NSString *)keyPath;


KVC 實現原理

1、[item setValue:@"白開水ln簡書" forKey:@"name"];

1.首先去模型中查找有沒有 setName,若有,直接調用賦值 [self setName:@"白開水ln簡書"]。

2.若無,去模型中查找有沒有 name 屬性,若有,直接訪問屬性賦值 name = value。

3.若無,再去模型中查找有沒有 _name 成員變量,若有,直接訪問屬性賦值 _name = value。

4.找不到,就會直接報找不到的錯誤(valueForUndefinedKey:)。


2、[item setValuesForKeysWithDictionary:dict];

1.遍歷字典中所有 key。

2.去模型中查找有沒有對應的屬性。



LNPerson *person = [[LNPerson alloc] init];

person.dog = [[LNDog alloc] init];

[person.dog setValue:@"阿黃" forKey:@"name"];

[person setValue:@"旺財" forKeyPath:@"dog.name"];

NSLog(@"%@", person.dog.name);

區別:forKey: 和 forKeyPath:

1、forKeyPath 包含了所有 forKey 的功能

2、forKeyPath 進行內部的點語法,層層訪問內部的屬性

3、注意:key 值一定要在屬性中找到,開發中最好使用forKeyPath。




KVO(Key-Value-Obersver)即鍵值監聽,利用一個key來找到某個屬性并監聽其屬性值得改變,當該屬性發生變化時,會自動的通知觀察者,這比通知中心需要post通知來說,簡單了許多。其實這也是一種典型的觀察者模式。

KVO 使用步驟

給目標對象的屬性添加觀察者

在回調方法中監聽屬性的變化

移除觀察者

// 1.添加觀察者

[self.person addObserver:self forKeyPath:@"name" options: NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];}

- (void)dealloc{

// 2.移除觀察者

[self.person removeObserver:self forKeyPath:@"name"];

}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(LNPerson *)person change:(NSDictionary *)change context:(void *)context{

NSLog(@"%@------%@------%@", keyPath, change);

}

KVO 實現原理

當一個類的屬性被觀察的時候,系統會通過runtime動態的創建一個該類的派生類,而且系統將這個類的isa指針指向了派生類,從而實現了給監聽的屬性賦值時調用的是派生類的setter方法。

還會在這個類的基類中重寫被觀察的屬性的setter方法,重寫的setter方法會在調用原setter方法前后,通知觀察對象值得改變

同時派生類還重寫了 class 方法以“欺騙”外部調用者它就是起初的那個類。

此外,派生類還重寫了 dealloc 方法來釋放資源。

KVO 實現原理

可以看到重寫的 setter 方法,給屬性賦值的前后分別調用了兩個方法。

- (void)willChangeValueForKey:(NSString *)key;

- (void)didChangeValueForKey:(NSString *)key;

而- (void)didChangeValueForKey:(NSString *)key;會調用

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • KCV 其實由于ObjC的語言特性,你根部不必進行任何操作就可以進行屬性的動態讀寫,這種方式就是Key Value...
    TYM閱讀 1,065評論 0 4
  • KVC KVC定義 KVC(Key-value coding)鍵值編碼,就是指iOS的開發中,可以允許開發者通過K...
    暮年古稀ZC閱讀 2,173評論 2 9
  • 作者:wangzz原文地址:http://blog.csdn.net/wzzvictory/article/det...
    反調唱唱閱讀 1,124評論 0 5
  • 由于Objective-C是基于Smalltalk進行設計的,所以它具有動態加載、動態綁定等特性。Key-valu...
    趙亦晨閱讀 1,099評論 0 0
  • KVC , KVO KVC和KVO的區別及應用 KVC/KVO原理 1. KVC鍵值編碼 KVC,即是指NSKey...
    旋葉閱讀 319評論 0 1