iOS开发 KVO底层实现初步了解

本文主要分为2个部分:KVO的基本底层原理,KVO容器类如何监听 。


一.基本原理

Apple中对KVO是这么说的:

Automatic key-value observing is implemented using a technique called isa-swizzling… When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class …

从上文的意思我们能够理解到,KVO的原理是,当我们去用KVO观察对象A的时候,动态的去生成一个A当前类的子类,然后去替换掉原来对象的isa指针,并且重写set方法,通过set方法去通知观察对象的属性是否发生了变化,如果发生变化再去通知,也就是说是被动通知。

我们来一步一步的验证一下

首先我们先创建一个对象,然后去用KVO去监听DXObject这个对象里面的dxStr属性。

_dxObject = [[DXObject alloc] init];

[_dxObject addObserver:self forKeyPath:@"dxStr" options:NSKeyValueObservingOptionNew context:nil];

然后去修改这个字符串,前面我们也说过了KVO的原理是通过重写set方法,所以这个时候我们要用点语法去给这个属性赋值,这样我们就能初步写出来一个监听事件

iOS开发 KVO底层实现初步了解_第1张图片

我们为了理解什么是动态的生成这个子类的对象,这个时候可以在添加监听前后打印一下这个对象,我们就会发现这样的情况

iOS开发 KVO底层实现初步了解_第2张图片

其实KVO就是创建了这个当前类的子类,用这个子类去监听这个地址内容的更改。

刚才我们也说道,替换之后又重写了dxStr的set的方法,那这个重写的set方法,其实里面是加了两个KVO的方法

- (void)willChangeValueForKey:(NSString *)key;

- (void)didChangeValueForKey:(NSString *)key;

那么我写一下这个set方法里面的操作,大概就是类似以下的实现方式。

iOS开发 KVO底层实现初步了解_第3张图片

所以说KVO并不是主动去查找监听,而是当这个属性走了set方法之后,他才会发起通知,告诉你它的值改变了,这也大大减少了性能的损耗。

二.KVO容器类如何监听

从前文来看,我们知道KVO的主要监听触发点在于set方法。那么如果是数组这样的添加对象,[_dxObject.dxArray addObject:_dxObject.dxStr],那么则不会执行set方法,所以也就无法监听了。

这也是很多的第三方出现的问题,那么这个时候我们可以利用KVC的方式去执行。

[[_dxObject mutableArrayValueForKey:@"dxArray"] addObject:@"1"];

那么这个方法实际上也是调用了KVO的方法,创建了一个子类对象去监听这个对象,然后再去添加KVO的通知方法。所以说KVC算是KVO的一个开始也就是入口。(在此感谢腾讯课堂老师们为我提供思路,各位如果还是不理解,可以去看看网上老师视频讲解)

你可能感兴趣的:(iOS开发 KVO底层实现初步了解)