KVO

作者: 愤怒小鸟飞呀飞 | 来源:发表于2018-05-16 15:21 被阅读0次
    KVO 概念

    KVO即Key-Value-Observing,顾名思义用于键值观察

    //通过此方法即可添加对象的观察者
    - (void)addObserver:(NSObject *)observer
             forKeyPath:(NSString *)keyPath
                options:(NSKeyValueObservingOptions)options
                context:(void *)context;
    
    使用场景

    1、NSProgress监听进度变化
    2、监听对象属性值的变化
    eg.

    @interface Person : NSObject{
        NSString *_name;
    }
    @property(nonatomic,copy)NSString *name;
    @end
    
    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
        _person = [[Person alloc] init];
        _person.name = @"huahua";
        [_person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
          [_person setValue:@"newHuahua" forKey:@"name"];
    }
    
    //观察者需要实现的方法
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        NSLog(@"observer receive change infomation");
    }
    
    实现原理解析
    • KVO 是基于runtime机制实现的
    • 当你观察一个对象时,一个新的类会动态的被创建。这个类继承自改对象原本的类,并重写了被观察属性的setter方法。自然,重写的setter方法会负责在调用原setter方法之前和之后,通知所有对象值的更改。最后把这个对象的isa指针(isa指针告诉RunTime系统这个对象的类是什么)指向这个新创建的子类,对象就神奇的变成了新创建的子类的实例。

    原来,这个中间类继承自原本的那个类。不仅如此,apple还重写了 -class方法,企图欺骗我们这个类没有变,就是原本那个类。
    eg.原类 Person,派生类NSKVONotifying_Person

    • 键值观察通知依赖于NSObject的两个方法:willChangeValueForKey:一定会被调用,继而observeValueForKey:ofObject:change:context:也会被调用。
    • 补充:KVO的这套实现机制中苹果还偷偷的重写了class方法,让我们误以为还是使用的当前类,从而隐藏生成的派生类

      如图: kvo原理分析.png
    • 如何自己实现KVO

    参考链接:https://www.zybuluo.com/MicroCai/note/66738
    https://www.jianshu.com/p/829864680648
    http://tech.glowing.com/cn/implement-kvo/

    相关文章

      网友评论

          本文标题:KVO

          本文链接:https://www.haomeiwen.com/subject/ixlpdftx.html