KVO原理与手动调用
一、KVO
KVO 是 Objective-C 对观察者模式(Observer Pattern)的实现。当被观察对象的某个属性发生更改时,观察者对象会获得通知。
二、KVO实现原理
- KVO是基于runtime机制实现的。
//创建Person对象,添加work属性
@interface Person : NSObject
@property(nonatomic,copy) NSString * work;
@end
当某个类(Person)的属性(work)对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类(NSKVONotifying_Person),在这个派生类中重写基类中任何被观察属性的setter 方法。派生类在被重写的setter方法内实现真正的通知机制
每个类对象中都有一个isa指针指向当前类,当一个类对象的第一次被观察,那么系统会偷偷将isa指针指向动态生成的派生类,从而在给被监控属性赋值时执行的是派生类的setter方法。
键值观察通知依赖于NSObject 的两个方法: willChangeValueForKey: 和 didChangevlueForKey:;在一个被观察属性发生改变之前, willChangeValueForKey:一定会被调用,这就 会记录旧的值。而当改变发生后,didChangeValueForKey:会被调用,继而observeValueForKey:ofObject:change:context: 也会被调用。
派生类中setter方法调用如下(伪代码):
@implementation NSKVONotifying_Person
-(void)setWork:(NSString *)work{
[self willChangeValueForKey:@"work"];
NSLog(@"派生类work");
[self didChangeValueForKey:@"work"];
}
@end
三、手动调用KVO
在Person类中添加类方法:
+(BOOL)automaticallyNotifiesObserversOfWork{
return NO;
}
在观察Person类work属性被观察时的变化:
上述方法返回NO,则组织自动调用键值观察方法,在Person work setter方法里手动调用:
-(void)setWork:(NSString *)work{
if (_work == work) {
return;
}
[self willChangeValueForKey:@"work"];
_work = work;
[self didChangeValueForKey:@"work"];
}
测试结果:
网友评论