KVO 实现原理

KVO 实现原理

KVO即Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。

KVO的原理

  1. 当一个object有观察者时,动态创建这个object的类的子类
  2. 对于每个被观察的property,重写其set方法
  3. 在重写的set方法中调用- willChangeValueForKey:和- didChangeValueForKey:通知观察者
  4. 当一个property没有观察者时,删除重写的方法
  5. 当没有observer观察任何一个property时,删除动态创建的子类

当我们在添加观察者的时候,打一个断点,在设置属性的时候打一个断点

发现对象P的isa指针居然变量了,指向的类也不是我们自己创建的,那也就说明是系统自己创建的,Person类的子类NSKVONotifying_Person,并且重写了set方法。其实,就是去判断有没有调用一个对象的set方法

现在我们就手动的模拟下这种情况

首先我们需要创建一个NSObject的分类,创建自己添加观察者的方法

@interface NSObject (KVO)
- (void)xf_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
@end

#import "NSObject+KVO.h"
#import <objc/runtime.h>
#import "XFKVONotifying_Person.h"

@implementation NSObject (KVO)

- (void)xf_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context {

    // 修改isa,改变当前对象的类名
    object_setClass(self, [XFKVONotifying_Person class]);

    //添加关联,把观察者保存到当前对象里
    objc_setAssociatedObject(self, @"observer", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

@end

由于我们使用了运行时,所以别忘记导入 <objc/runtime.h>

我们还需要创建一个 XFKVONotifying_Person类,并继承于 Person

#import "Person.h"

@interface XFKVONotifying_Person : Person

@end

#import "XFKVONotifying_Person.h"
#import <objc/runtime.h>

@implementation XFKVONotifying_Person

-(void)setAge:(NSInteger)age {

    [super setAge:age];

    //取出观察者,并通知观察者属性改变
    id observer = objc_getAssociatedObject(self, @"observer");
    
    [observer observeValueForKeyPath:@"age" ofObject:self change:nil context:nil];

}

@end

最后我们调用自己写的方法:

[p xf_addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];

一样可以观察到属性值的变化

总结

KVO底层实现原理:

  1. 动态创建NSKVONotifying_Person,NSKVONotifying_Person是Person子类,做KVO
  2. 修改当前对象的isa指针->NSKVONotifying_Person
  3. 只要调用对象的set,就会调用NSKVONotifying_Person的set方法
  4. 重写NSKVONotifying_Person的set方法:
  • [super set:]
  • 通知观察者,告诉你属性改变
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言 Key-Value-Observer,它来源于观察者模式, 其基本思想(copy于某度)是一个目标对象管理所...
    CholMay阅读 3,470评论 6 18
  • 一、概述 KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则其观察...
    DeerRun阅读 10,152评论 11 33
  • 作者:wangzz原文地址:http://blog.csdn.net/wzzvictory/article/det...
    反调唱唱阅读 1,130评论 0 5
  • 写响应式编程博客时,提到了KVO,今天我们探索一下KVO的实现原理及如何自己实现KVO功能 首先简单的KVO实现 ...
    Yochi阅读 1,752评论 2 2
  • 1.KVO概念 KVO即键值观察,它提供一种机制,当被观察的对象的属性发生改变后,对象会接收到通知,从而做出相应的...
    堂吉诃德灬阅读 315评论 0 2