KVO是如何实现的,探究一下
创建个Person类,非常简单的Person类,有一个属性就可以
来到控制器页面创建两个对象,一个KVO监听,一个不监听
输出结果
果然,添加了KVO监听的,可以输出变化,那监听的对象和没有监听的对象,到底有什么区别,搞出来看一下
通过调试可以发现person1对象添加了KVO监听的isa是指向NSKVONotifying_Person,而person2的isa是指向Person的
通过打印方法地址可以发现KVO监听之后就不再是从前的set方法了,是Foundation框架动态创建的方法
通过重写age属性的set方法、willChangeValueForKey方法和didChangeValueForKey方法,可以查看KVO内部调用流程
可以发现didChangeValueForKey会调用两次,didChangeValueForKey方法内部在set方法调用之后会立刻调用监听方法,最后调用再次调用didChangeValueForKey方法,完成值改变的监听
总结:KVO的本质是利用RuntimeAPI动态的生成一个子类,并让实例对象的isa指针指向这个新的子类,当修改实例对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数,调用willChangeValueForKey、父类的set方法、didChangeValueForKey,内部会触发监听器的监听方法observeValueForKeyPath:ofObject:change:context