KVC与KVO

通过KVC修改属性会触发KVO么?

我们知道使用KVC对属性赋值时,系统会去查找set方法,从而调用set方法,相当于set赋值所以肯定会触发KVO。
本质上来说KVC内部在修改成员变量的同时是会主动的调用调用willChangeValueForKey:只调用didChangeValueForKey:去触发KVO的,所以才会触发。
但是 直接修改成员变量不会触发KVO。直接修改成员变量内部并没有做处理只是单纯的赋值,所以不会触发。

还有一种情况,如果没有找到set方法呢,比如下面这个Person类就没有set方法

@interface Person : NSObject
{
    @public
    int age;
}
@end

@implementation Person

@end

@interface MObserver : NSObject

@end

@implementation MObserver

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

@end


MObserver *observer = [[MObserver alloc] init];
        
Person *person = [[Person alloc] init];
        
//添加KVO监听
[person addObserver:observer forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
//尝试用KVC修改属性
[person setValue:@10 forKey:@"age"];
        
[person removeObserver:observer forKeyPath:@"age"];

//打印:
 observeValueForKeyPath: {
    kind = 1;
    new = 10;
    old = 0;
}

从代码实现中我们看到没有set方法,也触发了KVO,说明是手动调用了willChangeValueForKey和didChangeValueForKey方法,从而触发了KVO。即:

[person setValue:@10 forKey:@"age"];
相当于以下三行代码
[person willChangeValueForKey:@"age"];
person->age = 10;
 [person didChangeValueForKey:@"age"];

因此

通过KVC修改属性会触发KVO监听,因为即使没有setter方法,但是[person setValue:@10 forKey:@"age”];内部会调用willChangeValueForKey和didChangeValueForKey方法,相当于手动触发了KVO。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。