iOS笔记 - KVO实现原理
作者:互联网
KVO实现原理
1 - 代码示例:
// - Person.h
1 #import <Foundation/Foundation.h> 2 @interface Person : NSObject 3 4 @property(nonatomic,assign)int age; 5 6 @end
// - Person.m
1 #import "Person.h" 2 @implementation Person 3 @synthesize age = _age; 4 5 // 没有添加观察者的对象,点语法依旧调用原来的 setter方法 6 - (void)setAge:(int)age{ 7 8 _age = age; 9 } 10 11 - (int)age{ 12 13 return _age; 14 } 15 16 17 // 添加了观察者的对象所调用 setter方法的实现如下(这些是在 runtime中动态生成) 18 // ---下面是伪代码,模拟实现流程------ 19 /* 20 - (void)setAge:(int)age{ 21 22 // setter方法里会执行 __NSSetInValueAndNotify函数(C语言私有函数,没有提示) 23 __NSSetInValueAndNotify(); 24 } 25 26 27 28 // __NSSetInValueAndNotify的实现 29 void __NSSetInValueAndNotify(){ 30 31 // 首先调用 willChangeValueForKey方法 32 [self willChangeValueForKey:@"age"]; 33 34 // 初始化实例变量 35 [super setAge:age]; 36 37 // 调用 didChangeValueForKey方法 38 [self didChangeValueForKey:@"age"]; 39 // 它会拿到 observer,调用 observeValueForKeyPath:ofObject:change:context方法 40 41 } 42 43 - (void)didChangeValueForKey:(NSString *)key{ 44 [observer observeValueForKeyPath:@"age" ofObject:self change:@{} context:nil] 45 } 46 47 **/ 48 @end
// - ViewController.m
1 #import "ViewController.h" 2 #import "Person.h" 3 @interface ViewController() 4 5 @end 6 7 @implementation ViewController 8 9 - (void)viewDidLoad { 10 [super viewDidLoad]; 11 self.view.backgroundColor = [UIColor cyanColor]; 12 13 14 Person *p1 = [Person new]; 15 // p p1->isa $1 = Person 16 p1.age = 100; 17 18 Person *p2 = [Person new]; 19 // p p2->isa $2 = Person 20 p2.age = 10000; 21 22 23 // 两者调用方法是一样的,都是同一个 setter 24 NSLog(@"%p",[p1 methodForSelector:@selector(setAge:)]); // 0x10f760390 25 NSLog(@"%p",[p2 methodForSelector:@selector(setAge:)]); // 0x10f760390 26 27 // p1添加观察者后,其 isa指针发生了变化 28 [p1 addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"传参"]; 29 // p p1->isa NSKVONotifying_Person 30 // 注意:NSKVONotifying_Person是 Person的子类 31 32 p1.age = 200; 33 p1.age = 300; 34 p2.age = 20000; 35 36 // p2调用的方法依旧是原来的 setter 37 NSLog(@"%p",[p2 methodForSelector:@selector(setAge:)]); // 0x10f760390 38 39 // p1 添加了观察者,setter方法发生了改变 40 NSLog(@"%p",[p1 methodForSelector:@selector(setAge:)]); // 0x7fff258f10eb 41 // 移除监听 42 [p1 removeObserver:self forKeyPath:@"age"]; 43 } 44 45 46 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ 47 48 NSLog(@"keyPath = %@ object = %@ change = %@",keyPath,object,change); 49 50 } 51 52 @end
关系图如下
标签:p2,p1,KVO,age,iOS,笔记,setAge,Person,void 来源: https://www.cnblogs.com/self-epoch/p/16316037.html