KVO 实现原理

期初,这个是因为朋友说的,忘记是哪所大公司的笔试题,说 KVO 的实现为什么要创建一个子类。当初,我还瞎说的做了一个回答,感觉这个也没啥呢。随着自己兴趣使然,我就简单搜索了一下,我天,铺天盖地的文献,才知道,原来这个也是个领域哦。

后来就慢慢的接触、了解,也听说了很多新词,其中陌生的要属 isa 指针了,因为当初这个东西只是在打断点的时候看过,但是从来不知道是干啥的,也没有深究过,另外一个是 Runtime 机制,好像一下子就把这个天天用也天天不在意的 KVO 提高了很高很高的档次,“有三四层楼那么高”—《功夫》!

然后,经过了差不多一个月左右的专研,给 isa 算是弄懂了,Runtime 看不懂,虽然知道什么:动态的创建类、更改执行的两个方法、动态的增加类的方法(Category),还有什么消息发送机制什么的,但是始终一头雾水。isa 我写了一篇白话技术档了,这里不再苦述。

那么,KVO 到底是啥子?用我们肯定会用,但是也保不齐用不好,不是忘记注册就是忘记移除的,要么就是那个新旧值的枚举都能写错的。暂且先算会用,比如一个类中的属性增加了监听,然后在监听回调方法中完成事件处理。那么注册监听的时候这个类都做了哪些事情呢?

首先、一个类的属性被注册了监听,那么就会:

创建一个类的元类,

创建一个类的元类,

创建一个类的元类,重要的事情说三遍,这里我必须要解释一下,因为好多文章都管这个叫做了新类。元类也是类,这里会涉及 isa 指针,也正是这个指针的特性和这个“新类”弄得我一个多小时都想不明白。

第一、isa 指针指向元类,它并不是指向父类,这个必须要牢记。元类不是父类,元类中有类的方法。

第二、对象收到消息后,就会在对象本身查找实例的方法,如果没有实现的方法,就会去找父类的元类,父类的元类就是父类的方法,子类继承父类,也就间接等于去父类里找方法了,所以这里是一个闭环。

第三、实例的实例方法存在于实例的类中,类的类方法存在于类的元类中,元类的方法存在于根元类中。所以类、元类、根元类就是存比它小一级的实例的方法的。

牢记上面以后,我们再接着来。

一个类的属性被注册了监听,那么就会创建这个类的元类,同时将 isa 指针指向新的元类,取名大概是 NSKVONotifying_objectName ,objectName 就是你监听的那个类的名字,然后,重写这个元类中的你监听的那个属性的 setter 方法,当有给类的属性赋值的操作的时候,Runtime 就按照 isa 指针的指引去这个元类中寻找调用 setter 方法,然后发送通知。

至于发送通知和对象接收通知的实现,那是关于 NSKeyValueObserving协议的履行,这里不做苦述。

你可能感兴趣的:(KVO 实现原理)