KVO的实现原理

KVO的实现原理

kvo的使用

// 头文件
#import "HMPerson.h"

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 运行时机制:runtime

    HMPerson *p = [[HMPerson alloc] init];
    p.age = 20;

    // 用KVO监听p对象age属性的改变
    [p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

    p.age = 30;
    self.p = p;
}

// 在对象被释放的时候一定要移除监听
- (void)dealloc
{
    [self.p removeObserver:self forKeyPath:@"age"];
}

/**
 *  当监控的某个属性的值改变了就会调用
 *
 *  @param keyPath 属性名(哪个属性改了?)
 *  @param object  哪个对象的属性被改了?
 *  @param change  属性的修改情况(属性原来的值、属性最新的值)
 *  @param context void * == id
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@对象的%@属性改变了:%@", object, keyPath, change);
}

KVO实现原理
利用运行时机制(runtime)系统内部会动态生成一个继承自HMPerson的子类NSKVONotifying_HMPerson。

重写HMPerson类的setAge方法:

#import "NSKVONotifying_HMPerson.h"

@implementation NSKVONotifying_HMPerson

- (void)setAge:(int)age
{
    [super setAge:age];

    // 通知监听器
    [监听器 observeValueForKeyPath:@"age" ofObject:self change:@{} context:nil];
}

@end

每个对象内部都会有个isa指针,isa指针指向哪里,就说明对象是哪个类,就会调用哪个类的方法。

在运行时,系统会动态吧p对象的isa指针指向 NSKVONotifying_HMPerson类

[p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];

所以之后再调这句代码的时候

 p.age = 30;

p对象的真实类型是NSKVONotifying_HMPerson,所以会调用NSKVONotifying_HMPerson的setAge方法,重写了setAge:方法,内部又会调用super 的aetAge:方法;所以父类的setAge:也会调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值