KVC/KVO 本质
KVO 的實現原理
KVO是關于runtime機制實現的
當某個類的對象屬性第一次被觀察時,系統就會在運行期動態地創建該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter方法。派生類在被重寫的setter方法內實現真正的通知機制
如果原類為Person,那么生成的派生類名為NSKVONotifying_Person
每個類對象中都有一個isa指針指向當前類,當一個類對象的第一次被觀察,那么系統就會偷偷講isa指針指向動態生成的派生類,從而在給被監控屬性復制是執行的是派生類的setter方法
鍵值觀察通知依賴于NSObject的兩個方法:willChangeValueForKey:和didChangeValueForKey:,在一個被觀察屬性發生改變之前,willChangeValueForkey:和didChangeValueForKey:;在一個被觀察屬性發生改變之前,willChangeValueForKey:一定會被調用,這就會記錄舊的值。而當改變發生后,didChangeValueForKey:會被調用,繼而observeValueForKey:ofObject:change:context:也會被調用
舉例偽代碼_NSSet*ValueAndNotify
- (void)setAge:(int)age {_NSSetIntValueAndNotify(); }// 偽代碼 void _NSSetIntValueAndNotify() {[self willChangeValueForKey:@"age"];[super setAge:age];[self didChangeValueForKey:@"age"]; }- (void)didChangeValueForKey:(NSString *)key {// 通知監聽器,某某屬性值發生了改變[oberser observeValueForKeyPath:key ofObject:self change:nil context:nil]; }KVC的實現原理
- KVC是Key Value Coding的簡稱。它是一種可以通過字符串的名字(key)來訪問類屬性的機制。而不是通過調用Setter、Getter方法訪問。KVC的方法定義在Foundation/NSKeyValueCoding中。
KVC使用的基本方法:
- (void)setValue:(nullableid)value forKey:(NSString*)key;//通過Key來設值 - (void)setValue:(nullableid)value forKeyPath:(NSString*)keyPath;//通過KeyPath來設值 - (nullableid)valueForKey:(NSString*)key;//直接通過Key來取值 - (nullableid)valueForKeyPath:(NSString*)keyPath;//通過KeyPath來取值KVC 賦值 setValue:forKey:
2.?若沒有找到Set方法,會調用對象的類方法+ (BOOL)accessInstanceVariablesDirectly;此方法返回YES時(默認返回YES),會按照_key,_iskey,key,iskey的順序搜索成員,然后賦值。
3.? 若都沒找到成員變量,將調用方法setValue:ForUndefinedKey:。并拋出異常 NSUnknowKeyException
KVC 取值值 valueForKey:
按先后順序搜索getKey:、key、isKey、三個方法,若某一個方法被實現,取到的即是方法返回的值,后面的方法不再運行。如果是BOOL或者Int等值類型, 會將其包裝成一個NSNumber對象。
若這三個方法都沒有找到,則會調用+ (BOOL)accessInstanceVariablesDirectly方法判斷是否允許取成員變量的值。若返回NO,直接調用- (nullable id)valueForUndefinedKey:(NSString *)key方法,并拋出異常 NSUnknowKeyException
若返回YES,會按先后順序取_key、_isKey、 key、isKey成員變量的值。調用- (nullable id)valueForUndefinedKey:(NSString *)key方法。
補充
KVC中的異常.獲取值時找不到key- (nullable id)valueForUndefinedKey:(NSString *)key;
設值時找不到key- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
- 如果你在SetValue方法時面給Value傳nil,則會調用這個方法
- (void)setNilValueForKey:(NSString *)key;
轉載于:https://www.cnblogs.com/ShaoYinling/p/10238492.html
總結
以上是生活随笔為你收集整理的KVC/KVO 本质的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 交通银行信用卡好现贷上征信吗?逾期的影响
- 下一篇: 还呗还款日几点扣款?还呗还款日期是什么时