KVO原理探索

作者: Breezes | 来源:发表于2020-08-05 09:57 被阅读0次

当一个类对某个对象的某个属性进行KVO监听时,系统为自动为该对象生成一个新的类,并把该对象的isa指针指向该类,以下面的Person类为例,通过代码看一下:

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@end

使用object_getClass方法分别获取person对象在KVO监听前后所属的类

Person *person = [Person new];
NSLog(@"observing before = %@",object_getClass(person));
[person addObserver:self forKeyPath:@"name" options:  
NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
NSLog(@"observing after = %@",object_getClass(person));

打印结果⬇️

2020-08-01 15:47:51.387800+0800 KVO原理探索[2812:151048] observing before = Person
2020-08-01 15:47:51.388244+0800 KVO原理探索[2812:151048] observing after = NSKVONotifying_Person

但是通过打印person对象会发现:


image.png

person还是属于Person类,这是因为派生类NSKVONotifying_Person重写了Class方法,以欺骗调用者。

那么接下来如何确定person的isa指针被重新指向了NSKVONotifying_Person?

交换指针需要使用object_setClass方法,通过条件断点检测设置KVO后是否调用object_setClass

image.png
详细文章请参考:https://juejin.im/post/6855129007928082446

生成派生类后是如何发送通知给监听者?

通过断点看一下派生类的setName方法:


image.png

通过上面的输出,我们了解到NSKVONotifying_Person类的setter方法转换为Foundation框架的_NSSetObjectValueAndNotify函数。
继续看堆栈信息,


image.png
通过堆栈信息,我们看出KVO的通知调用顺序:
1. -[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] 
2. -[NSObject(NSKeyValueObservingPrivate) _changeValueForKeys:count:maybeOldValuesDict:maybeNewValuesDict:usingBlock:] 
3.  -[Person setName:]
4.  NSKeyValueDidChange ()
5.  NSKeyValueNotifyObserver ()
6.  -[ViewController observeValueForKeyPath:ofObject:change:context:] 

总结一下:

使用KVO监听的person对象的isa指向了NSKVONotifying_Person类对象,那么他的set方法就在此类对象中,而且NSKVONotifying_Person类是Person的子类,当调用NSKVONotifying_Person的setName方法时,就会调用Foundation框架中的_NSSetObjectValueAndNotify方法。
_NSSetObjectValueAndNotify方法内部实现是:
首先调用willChangeValueForKey:
调用父类的setName:方法
调用didChangeValueForKey:当调用这个方法时内部就会触发监听器Oberser的监听方法observeValueForKeyPath:ofObject:change:context:这时候就能知道监听对象的属性值的改变了。

相关文章

  • iOS底层--KVO(一)-基础知识点

    KVO: 全称--- Key-value observing 探索KVO原理和KVO一样,通过官方文档去看。 KV...

  • KVO原理探索

    当一个类对某个对象的某个属性进行KVO监听时,系统为自动为该对象生成一个新的类,并把该对象的isa指针指向该类,以...

  • iOS探索KVO实现原理,重写KVO

    写响应式编程博客时,提到了KVO,今天我们探索一下KVO的实现原理及如何自己实现KVO功能 首先简单的KVO实现 ...

  • iOS KVO原理探索

    kvo全称Key-Value-Observing,俗称“键值监听”,可以用于对对象的某个属性值的监听。kvo是Ob...

  • KVO学习笔记

    1.KVO初探学习2.KVO 底层原理探索 1.KVO初探学习 移除观察者的重要性 (IOS11之后说不移除是不对...

  • GNUstep KVC/KVO探索(二):KVO的内部实现

    GNUstep KVC/KVO探索(一):KVC的内部实现GNUstep KVC/KVO探索(二):KVO的内部实...

  • GNUstep KVC/KVO探索(一):KVC的内部实现

    GNUstep KVC/KVO探索(一):KVC的内部实现GNUstep KVC/KVO探索(二):KVO的内部实...

  • KVO的原理

    KVO基本原理: KVO深入原理: 适用于:

  • iOS 探索KVO底层原理

    KVO底层原理 记 上一篇文章中说到,KVO监听成员变量无法收到回调。先验证一下是不是对的。 1.创建一个Pers...

  • iOS KVO底层原理探索

    一,KVO (Key-Value Observing) KVO是Objective-C对观察者设计模式的一种实现,...

网友评论

    本文标题:KVO原理探索

    本文链接:https://www.haomeiwen.com/subject/gcbyrktx.html