KVO的全称是Key -Value Observing,即“键值监听”,可用于监听某个对象属性值的改变
代码实现
结果输出
可以看到我们只监听了person1属性值改变,所以只输出person1的改变。那问题来了,我们给person1,person2都改变了age属性的值,本质都是调用了LGPerson类中setAge这个方法,那么为什么person1会走到oberveValueForKeyPath这个方法,person2不会呢? KVO底层实现分析 ——— 我们断点打印一下person1和person2的isa,看一下他们实例对象isa指向的类对象是什么?
person1的isa指针打印出的是NSKVONotifying_LGPerson,person2的isa指针打印出的是LGPerson 如果不监听person1的属性,我们看一下person1的isa指针
person1和person2都是实例对象,所以person1和person2的isa指针指向的都是类对象。 通过对比我们发现两者isa指针指向的对象发生了变化,现在我们再做深一步的研究,添加监听之后两者调用的setAge方法有没有变化呢
果然和我们猜想的一样,监听之后调用方法变成了_NSSetIntValueAndNotify 如果定义的属性是类型是double,则调用的是_NSSetDoubleValueAndNotify(),那么我们可以推测Foundation框架中有许多此类型的函数比如_NSSetBoolValueAndNotify,_NSSetCharValueAndNotify,_NSSetFloatValueAndNotify,通过属性的不同类型调用不同的函数。
NSKVONotifying_LGPerson内部结构解析
打印结果: 通过上述代码我们发现NSKVONotifying_LGPerson中有4个对象方法。分别为setAge: class dealloc _isKVOA
验证didChangeValueForKey:内部会调用observer的observeValueForKeyPath:ofObject:change:context:方法
打印结果: 通过打印内容可以看到,确实在didChangeValueForKey方法内部已经调用了observer的observeValueForKeyPath:ofObject:change:context:方法。