KVO

KVO

什么是KVO

KVO的全称是Key-Value Observing,俗称”键值监听”,可以用于监听某个对象属性值得改变

使用

1
2
3
4
5
6
7
// 监听someObj的someKey
NSKeyValueObservingOptions options = NSkeyValueObservingOptionNew | NSkeyValueObservingOptionOld;
[someObj addObserver:self forKeyPath:@"someKey" options:options context:nil];

// 当监听对象的属性值发生改变,就会调用
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
}

本质

KVO的本质是使用runtime动态生成一个NSKVONotifying_XXXClass的类,是原来类的子类。

NSKVONotifying_XXXClass的set方法中的操作大致为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 注:以下为伪代码

- setSomeKey:(id)someKey {
_NSSetIntValueAndNotify();
}

// Foundation框架中
void _NSSetIntValueAndNotify() {
[self willChangeValueForKey:@"someKey"];
[super setSomeKey: someKey];
[self. didChangeValueForKey:@"someKey"];
}

- (void)didChangeValueForKey:(NSString *)key {
// 通知监听器
[oberser observeValueForKeyPath:key ofObject: self, change: nil, context:nil];
}

扩展

  • 如何手动触发监听器
1
2
[someObject willChangeValueForKey:@"someKey"];
[someObject didChangeValueForKey:@"someKey"];
  • 直接修改成员变量会触发KVO么?

    不会,只有调用set方法才会调用KVO