美文网首页
OC观察者模式之KVO

OC观察者模式之KVO

作者: 芝麻酱的简书 | 来源:发表于2019-01-15 15:46 被阅读10次

KVO:

  • KVO是key-value observing的缩写
  • KVO是OC对观察者设计模式的又一实现
  • 苹果使用了isa混写(isa-swizzling)来实现KVO

1.KVO常用API

# observer是观察者,必须实现 
# options:KVO的一些属性配置:
NSKeyValueObservingOptionNew:change字典包括改变后的值
NSKeyValueObservingOptionOld:change字典包括改变前的值
NSKeyValueObservingOptionInitial:注册后立刻触发KVO通知
NSKeyValueObservingOptionPrior:值改变前是否也要通知(这个key决定了是否在改变前改变后通知两次)

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

2.禁用KVO

1). 禁用部分属性的KVO

  • 首先,需要手动实现属性的 setter方法,并在设置操作的前后分别调用 willChangeValueForKey:didChangeValueForKey方法,这两个方法用于通知系统该 key 的属性值即将和已经变更了;

  • 其次,要实现类方法 automaticallyNotifiesObserversForKey,并在其中设置对该 key 不自动发送通知(返回 NO 即可)。这里要注意,对其它非手动实现的 key,要转交给 super 来处理。

- (void)setName:(NSString *)name {
    [self willChangeValueForKey: @"name"];
    _name = name;
    [self didChangeValueForKey: @"name"];
}

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
    if ([key isEqualToString: @"name"]) {
        return NO;
    }
    return [super automaticallyNotifiesObserversForKey: key];
}

2). 禁用所有属性的KVO
如果需要禁用该类KVO的话直接automaticallyNotifiesObserversForKey返回NO,实现属性的setter方法,不进行调用willChangeValueForKey:didChangeValueForKey方法。

- (void)setName:(NSString *)name {
    _name = name;
}

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
    return NO;
}

3.isa混写技术在KVO中实现

派生类中实现:

- (void)setValue:(id)obj {
    [self willChangeValueForKey: @"keypath"];
    [super setValue: obj]
    
    # didChange方法触发监听回调
    [self didChangeValueForKey: @"keypath"];
}

当我们注册一个对象的观察者后,实际上是调用了系统的addObserver:ForKey:path:方法,系统会为我们在运行时动态的创建一个NSKVONotifying_被观察类的名字这样一个类,并将原来被观察的类的isa指针指向新创建的类(这一步就是isa混写技术的标志)。NSKVONotifying_被观察类的名字该类为原被观察类的子类,并重写了setter方法,来达到负责通知所有观察者这一目的。

Objective-C 在发送消息的时候,会通过 isa 指针找到当前对象所属的类对象。而类对象中保存着当前对象的实例方法,因此在向此对象发送消息时候,实际上是发送到了派生类对象的方法。由于编译器对派生类的方法进行了 override,并添加了通知代码,因此会向注册的对象发送通知。注意派生类只重写注册了观察者的属性方法。

4.KVO什么时候会生效:

  • 使用setter方法改变值会触发KVO
  • 使用setValue: forKey:改变值会触发KVO
  • 成员变量直接修改需要手动添加willChangedidChange方法,KVO才会触发

相关文章

  • iOS KVO的底层实现原理

    KVO 是 OC 观察者设计模式的一种KVO 的实现依赖于 OC 强大的 RuntimeKVO是Cocoa提供的...

  • iOS KVO观察者模式的深入理解

    谈到KVO我们就会联想到『观察者模式』,其实KVO就是在oc中实现观察者模式。那下面就对观察者做一个简单介绍: 观...

  • OC观察者模式之KVO

    KVO: KVO是key-value observing的缩写 KVO是OC对观察者设计模式的又一实现 苹果使用了...

  • KVO读书笔记

    KVO是什么 KVO 是 OC 对 观察者模式的实现。 KVO提供一种机制,指定一个被观察对象A,...

  • iOS KVO实现细节验证

    验证 KVO objective-c 中的 kvo 是观察者模式的一种oc实现。 不管使用方式了,直接看看kvo是...

  • iOS KVO 补充版

    1. 什么是KVO? KVO全称key-value observing; KVO是OC中观察者设计模式的又一个实现...

  • iOS KVO

    1. 什么是KVO? KVO全称key-value observeing; KVO是OC中观察者设计模式的又一个实...

  • iOS知识点小结

    1.KVO1.1> KVO 简介:KVO 是 OC 观察者设计模式的一种实现.KVO 指定一个被观察的对象的属性,...

  • 通知 /KVO、KVC相关

    如何实现通知机制? KVO ·kvo是OC对观察者设计模式的又一实现 ·APPLE使用了isa混写实现kvo KV...

  • KVO和KVC

    什么是KVO? KVO是对OC对于观察者设计模式的实现 apple使用了isa混写(isa-swizzling)来...

网友评论

      本文标题:OC观察者模式之KVO

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