KVO:键值监听
KVO的本质是什么?
利用runtime的动态特性生成了一个子类,并让instance对象的isa指向这个全新的子类
当修改instance对象的属性时候,会调用Foundation的_NSSetXXXValueAndNotify方法,
其内部调用了willChangeValueForKey 父类原来的setter didChangeValueForKey ,其内部会触发监听器Observer的监听方法 observeValueForKeyPath:ofObject:change:context:方法
如何手动触发KVO?
直接调用 willChangeValueForKey和didChangeValueForKey方法
直接修改成员变量会触发KVO么?
不会,因为没有触发set方法 ,可以通过willChangeValueForKey和didChangeValueForKey进行手动触发
在没有监听对象的时候 该对象的isa指向的类中 是只有isa superclass set get方法等 没有任何区别
如果增加监听后 该对象的isa指向的是一个通过runtime动态添加新生成的NSKVONotifying_xxx子类 该类中自己实现了set方法 该类中的superClass指向的是原来的类 ,而该新生成的子类的isa指向的自己的元类对象
由上图可以知道,原来的set方法里面生成了一个_NSSetXXValueAndNotify方法,内部调用了 willChangeVauleForKey 和didChangeValueForKey方法 中间调用了原有的super中的set方法进行赋值
调用didChangeValueForKey内部调用了observer的observerValueForKeyPath:ofObject:change:context:方法
如图:
重写了class方法为了是屏蔽内部实现,隐藏了NSKVONotifying_XXX类的存在