KVO
KVO即Key-Value-Observing,键值观察,是观察者模式的一种实现。KVO提供了一种机制能够方便的观察对象的属性。如:指定一个被观察对象,当对象的某个属性发生变化时,对象会获得通知,进而可以做出相应的处理。在实际的开发中对于model与controller之间进行交流是非常有用的。
KVO实现原理
官方文档具体描述如下:
Automatic key-value observing is implemented using a technique called isa-swizzling.
The isa pointer, as the name suggests, points to the object's class which maintains a dispatch table. This dispatch table essentially contains pointers to the methods the class implements, among other data.
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. As a result the value of the isa pointer does not necessarily reflect the actual class of the instance.
You should never rely on the isa pointer to determine class membership. Instead, you should use the class method to determine the class of an object instance.
KVO的实现依赖于OC强大的Runtime,上面文档也说道,KVO是通过使用isa-swizzling技术实现的。基本的流程是:当某个类的属性对象第一次被观察时,系统会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的setter方法,派生类在被重写的setter方法内实现真正的通知机制。
例如:当观察对象A时,KVO机制动态创建一个新类,名为NSKVONotifying_A。该类继承自对象A的类,并且重写了观察属性的setter方法,setter方法会负责在调用原setter方法之前和之后,通知所有观察者对象属性值的改变情况。
每个类对象都有一个isa指针,该指针指向当前类,当一个类对象的属性第一次被观察,系统会偷偷将isa指针指向动态生成的派生类,从而在给被监听属性赋值时执行的是派生类的setter方法。
派生类setter方法:
KVO的建值观察通知机制依赖于NSObject的两个方法,willChangeValueForKey:和didChangeValueForKey:,在进行存取数值前后分别调用这2个方法(因为我们所监的对象属性可以获取新值和旧值,所以属性改变前后都会通知观察者