其他分享
首页 > 其他分享> > iOS笔记 - KVO实现原理

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