iOS KVO 监听成员变量(非属性)


Demo地址
Demo中包含本人学习的所有资料,还有一些封装的Pod组件,欢迎下载Star,如果有错误的地方,还请指出,详情查看 README.md


KVO 研究

众所周知,KVO 可以监听属性 ,那么 KVO 可以监听成员变量吗?
答案是肯定的,下面通过代码来证明结论

测试代码

//添加 KVO ,监听 person 对象 的 _reName
-(void)addObserver{
    
    BSObjcPerson *person1 = [[BSObjcPerson alloc]init];
    self.person = person1;
    [person1 addObserver:self forKeyPath:@"_reName" options:NSKeyValueObservingOptionNew context:nil];
}

// KVO 回调
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    
    NSLog(@"observeValueForKeyPath == %@",keyPath);
    
    if ([keyPath isEqualToString:@"reName"]) {
        NSLog(@"reName : %@",self.person.reName);
    }
    
    if ([keyPath isEqualToString:@"_reName"]) {
        NSLog(@"_reName : %@",self.person.reName);
    }
}

// 通过 KVC 修改 person 的 reName 的值
-(void)changePersonName{
    [self.person setValue:@"222" forKeyPath:@"reName"];
    [self.person setValue:@"333" forKeyPath:@"_reName"];
}

测试结果

BSFrameworks_Example[81892:7139386] observeValueForKeyPath == _reName
BSFrameworks_Example[81892:7139386] _reName : 333

重写 person 对象 的 setReName 方法,发现通过

[self.person setValue:@"222" forKeyPath:@"reName"];

设置 reName 的值,会触发 setReName 方法,而 forKeyPath:@"_reName" 是不会触发 set 方法的,但是可以成功修改成员变量的 value


将测试代码修改下,在本 VC 中添加属性,然后 KVO 监听这个属性对应的成员变量,通过 成员变量直接赋值(_reName = @"123"),发现无法触发 KVO 回调


总结
  • KVO 可以通过成员变量监听,但是需要使用 KVC 更改成员变量的值,无法通过成员变量直接赋值触发 KVO,即: KVOkeyKVCkey 需要相同,都需要带 _
  • KVC 通过属性(不带 _)会触发 set 方法,所以 KVC 肯定可以通过设置属性的值来触发 KVO

你可能感兴趣的:(iOS KVO 监听成员变量(非属性))