http://xiongzenghuidegithub.github.io/blog/2016/05/16/kvo-part1/
对KVO的大致实现做个最终总结:
第一步、当一个对象的属性添加了属性观察者之后,这个对象的 isa指针会被修改
注意: 是这个对象的isa指针,而不是这个对象所属类的isa指针
第二步、由runtime在运行时创建出一个对象所属类的一个子类,名字的格式是NSKVONotifying_原始类名
第三步、重写原来父类中被观察属性property的setter方法实现
class_addMethod()
class_replaceMethod()
// 大致格式如下
- (void)setType:(NSSting *)type {
//1. 调用父类Cat设置属性值的方法实现
[super setType:type];
//2. 通知Cat对象的观察者执行回调(从断点效果看是同步执行的)
[cat对象的观察者 observeValueForKeyPath:@"type" ofObject:self change:@{} context:nil];
}
第四步、对象的 isa指针,由runtime系统替换指向为第二步中创建的中间类NSKVONotifying_原始类名
第五步、当对象的被观察属性值发生改变时(中间类的setter方法实现被调用),就会回调执行观察者的observeValueForKeyPath: ofObject:change:context:方法实现
从断点调用来看,这个回调过程是同步执行的
第六步,如下两个方法的返回的objc_class结构体实例是不同的
object_getClass(被观察者对象) >>> 返回的是替换后的中间类
[被观察对象 class] >>> 仍然然会之前的原始类
第七步、当对象移除属性观察者之后,该对象的isa指针又会恢复指向为原始类