KVC

iOS | KVC | Objective-C

通过KVC修改属性会不会触发KVO,KVC底层实现是什么样子?

1.KVC

KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性

常见API:

1
2
3
4
5
// 赋值
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForKey:(NSString *)key;

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

1
2
3
4
5
@implementation Observer
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
NSLog(@"%@", change);
}
@end
1
2
3
4
5
6
7
8
Observer *observer = [[Observer alloc] init];
Person *person = [[Person alloc] init];

[person addObserver:observer forKeyPath:@"age" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];

[person setValue:@20 forKey:@"age"];

[person removeObserver:observer forKeyPath:@"age"];

通过控制台输出,发现是可以触发KVO的

3.setValue:forKey

setValue:forKey:

1
[person setValue:@20 forKey:@"age"];

上面这行代码相当于下面这几行,在对属性赋值的时候系统内部会自动调用 willChangeValueForKey 和 didChangeValueForKey,所以会触发 KVO,可以重写这两个方法进行验证。

1
2
3
[person willChangeValueForKey:@"age"];
person->_age = 20;
[person didChangeValueForKey:@"key"];

4.valueForKey

valueForKey: