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