观察者模式---KVO介绍

KVO:

      key  value  observer,它提供一种当指定的对象属性被修改之后,则其观察者会接收到通知的机制。也就是说:被指定的观察对象的属性被修改之后,KVO就会自动通知相应的观察者了。这也是一种设计模式,用于两个类之间的解耦合,尤其是业务逻辑和试图控制器之间的解耦;

    self.p1 = [[Person alloc]init];
    self.p1.name = @"111";
    /*
     - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
     
     1 观察者,负责处理监听事件的对象
     2 观察的属性
     3 观察的选项
     *NSKeyValueObservingOptions
     NSKeyValueObservingOptionNew = 0x01,    新值
     NSKeyValueObservingOptionOld = 0x02,    旧值
     NSKeyValueObservingOptionInitial        初始值
     NSKeyValueObservingOptionPrior          之前的值
     4 上下文
     */
    [self.p1 addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
    //self.p1.name = @"123";

必须实现方法

//这个方法是NSObject的,任何对象都可以作为观察者
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    NSLog(@"监听到了%@的%@属性发生了改变", object, keyPath);
    NSLog(@"%@", change);
}

KVO的实现原理:

         KVO是基于Runtime机制实现的,当某个类的属性对象第一次被观察时,系统会在运行期动态的创建该类的派生类,在这个派生类中重写基类中任何被观察属性的setter方法;

例子:

原生类为Person,那么在运行期runtime会生成一个派生类:NSKVONotifying_person,继承自person类,每个类对象都有一个isa指针指向当前类,当一个类对象第一次被观察时,那么系统会将isa指针指向动态生成的这个派生类,从而在给被监控的属性赋值时执行的是派生类的setter方法。KVO依赖于NSObject的两个方法:

  1> willChangeValueForKey      在一个被观察的属性改变之前调用,记住这个值。

  2> didChangeValueForKey       在被观察的属性之后调用,才会调用observerValueForkey

解释:当person的name属性改变时,person对象的isa指针会指向NSKVONotifying_person,

-(void)setName:(NSString *)name
{
    //这两个方法的底层会调用-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(id *)change context:(void *)context
    [self willChangeValueForKey:@""];
    [self didChangeValueForKey:@" "];
}

猜你喜欢

转载自blog.csdn.net/ningn111/article/details/82183515