KVO :键值观察。当我们需要对某个对象的某个属性进行监听的时候,我们就利用KVO机制,通过属性关键字绑定,进行监听。
原理 :当某个对象A的某个属性被监听,系统会自动生成一个A的子类NSKVONotifing_A类,并重写setter方法,将被监听的A的实例对象的isa指针指向NSKVONotifing_A类。
想了解isa指针的可以看这里
为何要将isa指针指向子类?
如果不这样做,那么我们的isa依然是A类,那么在执行setter的时候,依然是A类的setter,并不是重写后的子类NSKVONotifing_A的setter方法,这样就不会执行通知更改触发。当isa改成NSKVONotifing_A后,就会先在NSKVONotifing_A的methodLists里寻找setter方法,而不是在A的methodLists中寻找(除非找不到setter才回去父类A中寻找)。
重写后的setter方法中会对属性值更改进行通知,分别以willChangeValueForKey:和didChangeValueForKey:进行触发。被观察属性发生改变之前,willChangeValueForKey:被调用,通知系统该 keyPath 的属性值即将变更,来保存旧值;当改变发生后,didChangeValueForKey:被调用,通知系统该 keyPath 的属性值已经变更;之后,observeValueForKey:ofObject:change:context:就会被调用。
手动触发KVO:
1、取消自动触发:重写+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
2、重写属性的setter方法,根据需求判断是否需要调用willChangeValueForKey:和didChangeValueForKey:方法。
NSMutableArray和NSMutableSet调用KVO
[[self.observedObject mutableArrayValueForKey:NSStringFromSelector(@selector(myArray))] addObject:object];
[[self.observedObject mutableSetValueForKey:NSStringFromSelector(@selector(mySet))] addObject:object];