KVO全称为Key-Value Observing, 即键值监听,用于指定对象属性值的改变。
定义如下一个Person类:
1 2 3
| @interface Person : NSObject @property (assign, nonatomic) int age; @end
|
给Person类的instance对象添加KVO:
1 2 3 4
| // 给person1对象添加KVO监听 NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld; [self.person addObserver:self forKeyPath:@"age" options:options context:nil];
|
当给Person的instance对象添加KVO监听后,Runtime会动态创建一个名为NSKVONotifying_Person的Person子类,并将instance对象的isa指针指向这个子类Class。
NSKVONotifying_Person类的setAge:方法的伪代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| - (void)setAge:(int)age { //调用Foundation框架的_NSSet***ValueAndNotify方法,与具体参数类型有关 _NSSetIntValueAndNotify(); }
void _NSSetIntValueAndNotify() { [self willChangeValueForKey:@"age"]; [super setAge:age]; [self didChangeValueForKey:@"age"]; }
- (void)didChangeValueForKey:(NSString *)key { // 通知监听器,属性值发生了改变 [oberser observeValueForKeyPath:key ofObject:self change:nil context:nil]; }
|
其他方法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| // 屏蔽内部实现,隐藏了NSKVONotifying_Person类的存在 - (Class)class { return [Person class]; }
- (void)dealloc { // 收尾工作 }
- (BOOL)_isKVOA { return YES; }
|
由此可见,直接修改成员变量的值不会触发KVO。