KVO 实现原理

作者: Aeron_Xie | 来源:发表于2016-02-17 15:43 被阅读564次

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:]
  • 通知观察者,告诉你属性改变

相关文章

  • iOS KVO

    KVO 示例 KVO的实现原理

  • 常见面试题--KVC和KVO

    1、KVO实现原理 2、KVC原理

  • 知识集锦

    https://github.com/starainDou 欢迎点星 KVO实现原理 KVO基本原理: 1 kvo...

  • iOS - 自定义KVO

    之前我们已经了解过了KVO的底层实现原理,不过呢,在我们开始实现自定义KVO之前再来简单回顾下KVO的实现原理 1...

  • iOS - KVO

    [toc] 参考 KVO KVC 【 iOS--KVO的实现原理与具体应用 】 【 IOS-详解KVO底层实现 】...

  • iOS原理篇(一): KVO实现原理

    KVO实现原理 什么是 KVO KVO 基本使用 KVO 的本质 总结 一 、 什么是KVO KVO(Key-Va...

  • iOS高级进阶之KVO

    KVO的原理 分析原理 使用 手动调用 自己实现KVO NSObject+KVOBlock.h NSObject+...

  • iOS 自定义KVO

    通过在了解KVO的实现原理和实现步骤之后,我们可以手动实现KVO,具体可以看最后的demo,这里只讲实现原理 添加...

  • iOS 进阶原理知识笔记

    KVO实现原理 KVO基本原理: 1 kvo是基于runtime机制实现的 2 当某个类的属性对象第一次被观察时,...

  • iOS 进阶原理知识随笔

    KVO实现原理 KVO基本原理: 1 kvo是基于runtime机制实现的 2 当某个类的属性对象第一次被观察时,...

网友评论

  • OutMan_Coder:您好 我按您的方法实现 最后为啥观察得不到属性改变的值:sweat:
    Aeron_Xie:@OutMan_Coder 我看下你的代码

本文标题:KVO 实现原理

本文链接:https://www.haomeiwen.com/subject/yhlmkttx.html