ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

iOS笔记 - KVO实现原理

2022-05-27 01:31:21  阅读:157  来源: 互联网

标签:p2 p1 KVO age iOS 笔记 setAge Person void


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有