KVO的监听机制

KVO监听 是通过对对象属性setter的监听实现

  • 首先我们写个KVO 简单栗子🌰
  • 写一个Dog类 拥有一个age属性
#import <Foundation/Foundation.h>
@interface Dog : NSObject
// 年龄
@property (nonatomic, assign) int age;
@end
  • 在控制器中监听 Dog的age属性
#import "ViewController.h"
#import "Dog.h"

@interface ViewController ()

@property (nonatomic, strong) Dog *dog;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    Dog *dog = [[Dog alloc] init];
    _dog = dog;
    
    // 监听dog的age属性
    [dog addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];
    
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
    NSLog(@"age is %d", _dog.age);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    _dog.age++;
}

@end

此时运行程序 点击屏幕输出

此时 age值一改变 我们在监听方法中立马能知道值的变化
为了验证 KVO是通过 属性的setter方法去监听
修改下方法

直接访问成员变量
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//    _dog.age++;
    _dog-> _age++;
}

此时会报错 因为 @property 会生成私有的成员变量 将其声明为public

@interface Dog : NSObject {
    @public
    int _age;
}
//年龄
@property (nonatomic, assign) int age;

@end

此时再运行 点击屏幕 发现没有输出了

为验证是否执行了 监听方法 在监听方法里打上断点

说明 监听方法 确实执行了

从而也证明了 KVO底层是对对象属性setter 的监听

============================

继续研究KVO的原理
  • 在添加观察者之前 打上断点 观察此时dogisa指针

此时dogisa指针指向它的父类 Dog

单步执行 添加完 监听者以后 再观察isa指针

此时 `isa` 指针已经不再指向`Dog`   指向`NSKVONotifying_Dog`

调用 `dog`属性的`setter` 将不再去类`Dog` 中去找了  而是去类`NSKVONotifying_Dog`中找

在`NSKVONotifying_Dog`类中 重写`setter`通知观察者值的改变


修改`isa` 本质是就是修改当前对象的类名
`Class object_setClass(id object, Class cls)`
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,840评论 0 9
  • 喜欢就关注我呗! 1.设计模式是什么? 你知道哪些设计模式,并简要叙述? 设计模式是一种编码经验,就是用比较成熟的...
    iOS白水阅读 1,135评论 0 2
  • 一、深复制和浅复制的区别? 1、浅复制:只是复制了指向对象的指针,即两个指针指向同一块内存单元!而不复制指向对象的...
    iOS_Alex阅读 1,463评论 1 27
  • 《招聘一个靠谱的 iOS》—参考答案(下) 说明:面试题来源是微博@我就叫Sunny怎么了的这篇博文:《招聘一个靠...
    Mominglaile阅读 1,239评论 0 1
  • 友情是一种神奇的情感。 萧芝和顾曦两个人从小一起长大,形影不离,一起挖过老王家的番薯和偷过老奶奶家的鸡蛋。放学揣着...
    蛋塔阅读 867评论 0 0