[孙源sunnyxx]&objc kvo简单探索
[转载]objc kvo简单探索
KVO(Key Value Observing),是观察者模式在Foundation中的实现
KVO的原理
简而言之就是:
- 当一个object有观察者时,动态创建这个object的类的子类
- 对于每个被观察的property,重写其
set方法 - 在重写的
set方法中调用- willChangeValueForKey:和- didChangeValueForKey:通知观察者 - 当一个property没有观察者时,删除重写的方法
- 当没有observer观察任何一个property时,删除动态创建的子类
空说无凭,简单验证下。
@interface Sark : NSObject
|
测试代码:
Sark *sark = [Sark new];
|
断住后分别使用- class和object_getClass()打出sark对象的Class和真实的Class
// breakpoint 1
|
上面的结果说明,在sark对象被观察时,framework使用runtime动态创建了一个Sark类的子类NSKVONotifying_Sark
而且为了隐藏这个行为,NSKVONotifying_Sark重写了- class方法返回之前的类,就好像什么也没发生过一样
但是使用object_getClass()时就暴露了,因为这个方法返回的是这个对象的isa指针,这个指针指向的一定是个这个对象的类对象
然后来偷窥一下这个动态类实现的方法,这里请出一个NSObject的扩展NSObject+DLIntrospection,它封装了打印一个类的方法、属性、协议等常用调试方法,一目了然。
@interface NSObject (DLIntrospection)
|
然后继续在刚才的断点处调试:
// breakpoint 1
|
首先就有个扎眼的- .cxx_destruct冒出来,这货是个啥?详细的探究请参考我的另一篇文章。
大概就是说arc下这个方法在所有dealloc调用完成后负责释放所有的变量,当然这个和kvo没啥关系了,回到正题。
从上面breakpoint2的打印可以看出,动态类重写了4个方法:
- setName:最主要的重写方法,set值时调用通知函数- class隐藏自己必备啊,返回原来类的class- dealloc做清理犯罪现场工作- _isKVOA这就是内部使用的标示了,判断这个类有没被KVO动态生成子类
接下来验证一下KVO重写set方法后是否调用了- willChangeValueForKey:和- didChangeValueForKey:
最直接的验证方法就是在Sark类中重写这两个方法:
@implementation Sark
|
没问题。
原创文章,版权声明:署名-非商业性使用-相同方式共享 2.5
对博主感兴趣?微信订阅号中关注 sunnyxx 或关注微博@我就叫Sunny怎么了
© 2015 - 2016 sunnyxx | Powered by Hexo
T

浙公网安备 33010602011771号