KVO原理

简介

  • 主角:KVO
  • 全称:KeyValueObserving
  • 所属:通知机制
  • 形式:一对一
  • 作用:允许A对象监听B对象某个属性的改变
  • 使用要求:继承自NSObject的对象

API和属性

  • 监听方法
/// 监听方法
/// @param observer 监听对象
/// @param keyPath 被监听对象的属性
/// @param options 选项
/// @param context 其他信息
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;

  • 必须实现的回调方法
/// kvo回调方法
/// @param keyPath 对象的属性
/// @param object 被监听对象
/// @param change 字典 变化信息 包括 NSKeyValueChangeNewKey等key
/// @param context 额外数据
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context;

  • 移除方法
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
  • 使用举例

dog对象 监听 person对象age的最新变化

[self.person addObserver:self.dog forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];

dog对象的类里实现

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    NSLog(@"狗监听到%@对象的%@属性改变了",object,keyPath);
    //新值
    NSString *newV = change[NSKeyValueChangeNewKey];
    //旧值
    NSString *oldV = change[NSKeyValueChangeOldKey];
    
    NSLog(@"newV:%@",newV);
    NSLog(@"oldV:%@",oldV);
    
}

移除监听

 [self.person removeObserver:self.dog forKeyPath:@"age"];

底层原理

KVO底层是基于runtime机制实现的

  • 第一步
    A类的对象第一次被B类的对象监听时,系统就会在运行时动态给A类的对象搞一个派生类(继承自A),类名为NSKVONotifying_A,在NSKVONotifying_A类中重写被B类对象监听的属性

  • 第二步
    系统会将A类的isa指针会指向NSKVONotifying_A,这时A类的对象的属性被赋值时实际上就是走的NSKVONotifying_A类的属性的setter方法

  • 第三步
    在这个setter方法中,是这样的(借用上面人和狗的例子)


- (void)setAge:(int)age
{
    [self willChangeValueForKey:@"age"];
    
    [self setValue:age forKey:@"age"];//赋值
    
    [self didChangeValueForKey:@"age"];
}

这里,在赋值中会走两个方法,在赋值之前调用了willChangeValueForKey,赋值之后调用了 didChangeValueForKey,然后调用 observeValueForKey:ofObject:change:context:,所以B类的对象就接收到变化信息了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值