KVO监听选项

作者: 郝嗨森 | 来源:发表于2019-01-25 15:26 被阅读0次

    官方文档介绍

    KVO注册方法

    - (void)addObserver:(NSObject *)observer 
             forKeyPath:(NSString *)keyPath 
                options:(NSKeyValueObservingOptions)options 
                context:(nullable void *)context;
    

    第三个参数NSKeyValueObservingOptions是一个枚举,用来设置何时触发通知以及要监听的状态。

    typedef NS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) {
            NSKeyValueObservingOptionNew = 0x01,
            NSKeyValueObservingOptionOld = 0x02,
            NSKeyValueObservingOptionInitial = 0x04,
            NSKeyValueObservingOptionPrior = 0x08
    };
    

    NSKeyValueObservingOptionNew
    表示捕获被观察属性变化后的值,并且只在值发生变化后触发通知。

    // 只指定了NSKeyValueObservingOptionNew
    {
        kind = 1;
        new = "new value";
    }
    

    NSKeyValueObservingOptionOld
    表示捕获被观察属性变化前的值,并且只在值发生变化后触发通知。

    // 只指定了NSKeyValueObservingOptionOld
    {
        kind = 1;
        old = "old value";
    }
    // 同时指定了NSKeyValueObservingOptionNew和NSKeyValueObservingOptionOld
    {
        kind = 1;
        new = "new value";
        old = "old value";
    }
    

    注意:如果指定的选项只是old和new中的一个或两个,那么通知触发时机就是在发生变化后,并且指定了哪个就包含哪个对应的值。

    NSKeyValueObservingOptionInitial
    表示在调用注册方法时会自动触发一次通知,在值发生变化后也是会触发通知的。如果指定了NSKeyValueObservingOptionOld和NSKeyValueObservingOptionNew,那么只会包含新值,不会包含旧值,因为虽然此时属性的值是旧值,但是对于观察者来说是新的。

    // 只指定了NSKeyValueObservingOptionInitial
    {
        kind = 1;
    }
    // 同时指定了NSKeyValueObservingOptionInitial、NSKeyValueObservingOptionOld和NSKeyValueObservingOptionNew,通知中只会包含新值
    {
        kind = 1;
        new = "initial value";
    }
    

    NSKeyValueObservingOptionPrior
    表示在变化前后各发送一次通知,同时变化前通知字典会多包含一个字段notificationIsPrior = 1;

    // 只指定了NSKeyValueObservingOptionPrior,变化前后两个通知字典内容分别如下:
    {
        kind = 1;
        notificationIsPrior = 1;
    }
    {
        kind = 1;
    }
    // 如果同时指定了NSKeyValueObservingOptionOld,那么两次通知中都会包含旧值
    {
        kind = 1;
        notificationIsPrior = 1;
        old = "old value";
    }
    {
        kind = 1;
        old = "old value";
    }
    // 如果同时指定了NSKeyValueObservingOptionNew,那么只在发生变化后的通知中会包含新值
    {
        kind = 1;
        notificationIsPrior = 1;
    }
    {
        kind = 1;
        new = "new value";
    }
    // 如果同时又指定了NSKeyValueObservingOptionOld和NSKeyValueObservingOptionNew
    // 变化前后通知的内容
    {
        kind = 1;
        notificationIsPrior = 1;
        old = "old value";
    }
    {
        kind = 1;
        new = "new value";
        old = "old value";
    }
    // 如果四种类型都指定了,会是什么情况呢?
    // 初始化时触发一次通知,和同时指定initial和new是一样的。
    {
        kind = 1;
        new = "initial value";
    }
    // 变化前后通知的内容
    {
        kind = 1;
        notificationIsPrior = 1;
        old = "old value";
    }
    {
        kind = 1;
        new = "new value";
        old = "old value";
    }
    

    NSKeyValueObservingOptionInitialNSKeyValueObservingOptionPrior控制触发通知的时机,NSKeyValueObservingOptionNewNSKeyValueObservingOptionOld用来控制获取变量不同状态的值。

    补充
    可以看到,每个通知字典中都会包含一个字段kind,那这个kind是什么意思呢?顾名思义,kind指的是类型,在这里就是指可以观察的属性值发生变化的类型,它的取值是一个枚举:官方文档

    typedef NS_ENUM(NSUInteger, NSKeyValueChange) {
        NSKeyValueChangeSetting = 1,
        NSKeyValueChangeInsertion = 2,
        NSKeyValueChangeRemoval = 3,
        NSKeyValueChangeReplacement = 4,
    };
    

    常见的类型就是setting,即kind=1,另外三个指的是to-many关系中的插入、删除和替换,至于具体什么是to-many、to-one关系,本人尚未明了,请多多指教!

    相关文章

      网友评论

        本文标题:KVO监听选项

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