KVO原理与手动调用

2018-07-11  本文已影响26人  JeromeZhao

KVO原理与手动调用

一、KVO

KVO 是 Objective-C 对观察者模式(Observer Pattern)的实现。当被观察对象的某个属性发生更改时,观察者对象会获得通知。

二、KVO实现原理

//创建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"];
}

测试结果:


上一篇 下一篇

猜你喜欢

热点阅读