本帖最后由 老旭谈IT 于 2017-12-6 15:05 编辑
KVO的底层是怎么实现的?1:KVO是基于Runtime机制实现的
2:当某个类的对象第一次被观察时,系统就会在运行期动态的创建该类的一个派生类,在这个派生类中重写基类以及被观察属性的setter方法,派生类在被重写的setter方法实现真正的通知机制(Person->NSKVONotifying_Person) 后面我们对KVO的底层进行一个分析业务需求人的年龄改变了,那么狗得知道人的年龄改变了 1:我们先新建一个项目
屏幕快照 2016-04-21 上午10.55.38.png
2:新建两个类
a:一个Person类 Person 有一个age年龄属性b: 一个Dog类
屏幕快照 2016-04-21 上午10.58.44.png
3:我们在ViewController去实现点击屏幕修改person的年龄属性 #import "ViewController.h"#import "Person.h"#import "Dog.h"@interface ViewController ()@property (nonatomic, strong) Person *person;@property (nonatomic, strong) Dog *dog;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.person = [[Person alloc]init]; self.dog = [[Dog alloc]init];}-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ self.person.age = 10;}@end4:接下来再去给person增加一个方法 #import "ViewController.h"#import "Person.h"#import "Dog.h"@interface ViewController ()@property (nonatomic, strong) Person *person;@property (nonatomic, strong) Dog *dog;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.person = [[Person alloc]init]; self.dog = [[Dog alloc]init]; //这个方法的意思是什么,就是让self.dog知道self.person,的age改变了,也就是self.dog成为self.person的监听 [self.person addObserver:self.dog forKeyPath:@"age" options:0 context:nil];}-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ self.person.age = 10;}@end5:接下来我们去Dog类里面实现一个方法(注意注释) #import "Dog.h"@implementation Dog-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{ //这个方法什么意思?来到这里其实就是狗知道了person的年龄改变了 NSLog(@"狗知道了%@的%@改变了",object,keyPath);}@end6:我们把项目运行起来,看是否实现我们的需求
屏幕快照 2016-04-21 上午11.21.43.png
可以看到,控制台输出了,狗知道了person的age改变了 7:此时我们就简单的实现了我们的需求,是用的是KVO去实现
那KVO的底层到底是怎么实现的呢?为什么会去调用Dog的 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{ //这个方法什么意思?来到这里其实就是狗知道了person的年龄改变了 NSLog(@"狗知道了%@的%@改变了",object,keyPath);}8:其实是这样,我们KVO监听的属性被改变的时候,系统会给我们生存一个派生类,并且这个类是继承Person类的,并且在年龄改变的时候,会重写属性的setter方法
屏幕快照 2016-04-21 上午11.26.56.png
可能大家还不觉得是真的重写了这个类的setter方法,我给大家看一下他Person的isa指针到底是啥。
|