KVO 2020-06-25

KVO是Key-value observing的缩写

KVO是Objective-C对观察者模式的又一实现

Apple使用了isa混写(isa-swizzling)来实现KVO


KVO和NSNotificationCenter都是iOS中观察者模式的一种实现。区别在于,相对于被观察者和观察者之间的关系,KVO是一对一的,而不一对多的。KVO对被监听对象无侵入性,不需要修改其内部代码即可实现监听。

KVO可以监听单个属性的变化,也可以监听集合对象的变化。通过KVC的mutableArrayValueForKey:等方法获得代理对象,当代理对象的内部对象发生改变时,会回调KVO监听的方法。集合对象包含NSArray和NSSet。

基础使用

使用KVO分为三个步骤:

通过addObserver:forKeyPath:options:context:方法注册观察者,观察者可以接收keyPath属性的变化事件。

在观察者中实现observeValueForKeyPath:ofObject:change:context:方法,当keyPath属性发生改变后,KVO会回调这个方法来通知观察者。

当观察者不需要监听时,可以调用removeObserver:forKeyPath:方法将KVO移除。需要注意的是,调用removeObserver需要在观察者消失之前,否则会导致Crash。


kvo重写setter添加的方法,setter方法会调用_NSSetXXValueAndNotify(XX为类型)方法,_NSSetXXValueAndNotify会调用一些方法

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

[super set方法]

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


伪代码

使用setter方法改变值KVO才会生效

使用setValue:forKey:改变值KVO才会才会生效

成员变量直接修改需手动添加KVO才会生效



KVO结构

如上图,派生类会重写class方法,直接返回Person类,隐藏内部实现。如想得到派生类的类对象,可用object_getClass(self.persion)

题外话,NSObject里面的class实现应该是

-(Class)class{

        object_getClass(self)

}

你可能感兴趣的:(KVO 2020-06-25)