KVC与KVO

作者: 凌云01 | 来源:发表于2020-08-11 10:45 被阅读0次

通过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。

相关文章

网友评论

      本文标题:KVC与KVO

      本文链接:https://www.haomeiwen.com/subject/utyedktx.html