(转)kvo

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指针又会恢复指向为原始类

你可能感兴趣的:((转)kvo)