kvo
的全稱是
key-value
observing
,俗稱「鍵值監聽」,可以用於監聽某個物件屬性值的改變。
下面來**一下kvo的本質
1.新建乙個xzperson類
#import
@inte***ce xzperson : nsobject
@property(nonatomic,assign)int age;
@end
#import "xzperson.h"
@implementation xzperson
- (void)setage:(int)age
- (void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary*)change context:(void *)context
- (void)dealloc控制台列印結果如下:
2018-10-10 10:27:39.808750+0800 kvotest[1067:45659] person1新增kvo之前-xzperson-0x1022fe4b0-0x1022fe4b0
2018-10-10 10:27:39.809313+0800 kvotest[1067:45659] person1新增kvo之後-nskvonotifying_xzperson-0x1026a3f8e-0x1022fe4b0
2018-10-10 10:27:39.809650+0800 kvotest[1067:45659]新增kvo後的person的父類xzperson
(lldb) p imp(0x1022fe4b0)
(imp) $0 = 0x00000001022fe4b0 (kvotest`-[xzperson setage:] at xzperson.m:14)
(lldb) p imp(0x1026a3f8e)
(imp) $1 = 0x00000001026a3f8e (foundation`_nssetintvalueandnotify)
(lldb)
由此可以看出:person1 在新增kvo監聽之後,生成了乙個nskvonotifying_xzperson的類,其父類為xzperson;
使用lldb檢視person1的setage方法的實現,發現新增kvo之後的person1在setage方法內部呼叫了foundation 的`_nssetintvalueandnotify方法,這裡涉及到foundation框架的反編譯。此方法的偽**如下:
- (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];
總結:willchangevalueforkey
:父類原來的
setter
didchangevalueforkey
:2.如何手動觸發kvo?
手動呼叫
willchangevalueforkey:和
didchangevalueforkey
:方法
KVO實現原理
kvo的執行原理是基於執行時的 當乙個物件註冊了監聽者以後 程式執行時就會動態的建立被監聽者的乙個子類 nskvonotifying 建立該子類的物件 kvo只能監聽物件屬性通過setter方法改變時監聽 1 當乙個object有觀察者時,動態建立這個object的類的子類 2 對於每個被觀察的pr...
KVO 實現原理
1.self.person 要監聽的物件 2.引數說明 param addobserver 觀察者,負責處理監聽事件的物件 param forkeypath 要監聽的屬性 param options 觀察的選項 觀察新 舊值,也可以都觀察 param context 上下文,用於傳遞資料,可以利用上...
kvo實現原理 KVC KVO實現原理
一 kvc運用了乙個isa swizzling技術。isa swizzling就是型別混合指標機制。kvc主要通過isa swizzling,來實現其內部查詢定位的。isa指標,如其名稱所指,就是is a kind of的意思 指向維護分發表的物件的類。該分發表實際上包含了指向實現類中的方法的指標,...