KVO的实现原理探寻
一讲到KVO好像很神奇很厉害的样子,那究竟是什么原理呢
首先,我们先来见一个最简单的KVO
新建一个Person类,就一行代码
@property (nonatomic, assign) int age;
然后在viewController中调用一下
- (void)viewDidLoad {
[super viewDidLoad];
_p = [[Person alloc] init];
_p.age = 10;
[_p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
_p.age = 20;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"%@对象的%@属性改变:%@", object, keyPath, change);
}
- (void)dealloc
{
[_p removeObserver:self forKeyPath:@"age"];
}
输出结果:
<Person: 0x7f7fcb6678e0>对象的age属性改变:{
kind = 1;
new = 20;
old = 10;
}
下面进入正题,我们打两个断点调试一下
第一个断点给age赋值的时候,P的isa指针指向的是Preson,说明是Person类
当增加完监听以后,神奇的事情发生了,P的isa指针指向了NSKVONotifying_Person,显然我们是没有创建过这个类的,
那一定是自动创建的了
然后我们打印一下setAge地址看看:
NSLog(@"%p",method_getImplementation(class_getInstanceMethod(objc_getClass("Person"), @selector(setAge:))));
NSLog(@"%p",method_getDescription(class_getInstanceMethod(objc_getClass("NSKVONotifying_Person"), @selector(setAge:))));
输出结果 ;
0x103ffb9a0
0x7fddaa69fe58
总结:过多的就不探寻了,推测应该是系统自动创建了一个 NSKVONotifying_Person 类继承自 Person,并重写了set方法,这样就能够知道什么时候键值发生了改变