KVO

作者: 远辰jt | 来源:发表于2018-06-05 14:36 被阅读11次

KVO是观察者设计模式在Foundation框架中的应用。

1,相关API

苹果给NSObject提供了一个分类,提供了三个方法

@interface NSObject(NSKeyValueObserverRegistration)
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
@end
该分类提供了一个添加观察者和两个移除观察者的方法,移除观察者的两个方法中一个带有上下文参数,一个不带,苹果建议使用带有上下文参数的api,因为该方法可以精确的指定要移除的对象,如果不带上下文参数的话还需要系系统去推测,当一个对象重复注册同一个keypath的时候有可能推断错误

如果想观察某个对象的属性的变化,可以先添加观察者,实现代理方法,然后在适当的时候移除观察者即可。 当添加完观察者后,如果观察的属性发成变化会调用观察者的下面的方法

- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;

注意: 当一个对象添加了多个keypath观察的时候,无论哪一个属性发生变化都会走这个方法, 好在方法参数带有发生变化时的值,对象和上下文, 可以据此加以区分

2,实现原理

kvo的底层实现用到了运行时,当向一个对象的某个属性添加观察者时,系统会利用运行时动态创建一个该类的子类,并且在子类中重写该属性的set方法, 然后在子类重写的方法中, 先调用即将赋值的方法,然后调用赋值方法,然后再调用已经赋值完成的方法。这样当对象的属性发展变化的时候就能及时的通知观察者。
如果移除了属性的观察者, 那么子类中属性的重写方法也会被移除。
如果移除了一个对象的所有观察者,那么其子类也会自动被移除
代码验证可以看参考http://blog.sunnyxx.com/2014/03/09/objc_kvo_secret/

3,作用

个人感觉如果需要持续性间断的获取某个值的时候可以考虑使用kvo, 例如检测下载进度,网页的加载进度和图片的加载进度。最近我就需要 了一个需求需要动态获取网页的内容高度, 网页比较简单,就是加载文字和图片。因为加载过程需要一定的时间,一次性获得的高度有可能不对,这时候布局的话就是不正常的。

4, 注意点

1,当父类和子类都添加属性观察时,无论是父类还是子类观察的属性发生变化的时候都会调用子类的回调方法,所以在子类的回调方法中要注意判断,不能阻断了父类的响应链

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    if (object == self.view) {
        // 判断如果是子类监听的属性 做操作  否则调用父类方法,将响应率交给父类
    }
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}

可以在添加监听的时候指定唯一的content 然后在回调方法中就可以判断然后做不同的处理

[self.webView addObserver:self forKeyPath: @"frame" options:NSKeyValueObservingOptionNew context:@"asdfasdf"];

这样添加监听后就可以在回调方法中根据标识  asdfasdf   来唯一确定

2,要避免同一个对象对同一个path的多次监听
参考文字https://blog.csdn.net/chenyong05314/article/details/50421280

5,如何对MutableArray的改变添加监听

https://www.jianshu.com/p/55586c822ca8

相关文章

  • iOS原理篇(一): KVO实现原理

    KVO实现原理 什么是 KVO KVO 基本使用 KVO 的本质 总结 一 、 什么是KVO KVO(Key-Va...

  • 04. KVO使用,原理,本质

    问题 KVO日常使用 KVO原理(KVO本质是什么) 如何手动触发KVO 直接修改成员变量会触发KVO吗 KVO图...

  • 20.iOS底层学习之KVO 原理

    本篇提纲1、KVO简介;2、KVO的使用;3、KVO的一些细节;4、KVO的底层原理; KVO简介 KVO全称Ke...

  • 深入理解KVO

    iOS | KVO | Objective-C KVO的本质是什么,如何手动触发KVO? 1.什么是KVO KVO...

  • OC语法:KVO的底层实现

    一、KVO是什么二、怎么使用KVO三、KVO的底层实现四、KVO常见面试题 一、KVO是什么 KVO全称Key-V...

  • KVO基本使用

    分三部分解释KVO一.KVO基本使用二.KVO原理解析三.自定义实现KVO 一、KVO基本使用 使用KVO,能够非...

  • KVO 解析

    KVO解析(一) —— 基本了解KVO解析(二) —— 一个简单的KVO实现KVO解析(三) —— KVO合规性K...

  • KVO

    目录 1. KVO的使用1.1 KVO基本使用方法1.2 KVO手动触发模式1.3 KVO属性依赖1.4 KVO容...

  • OC语言之KVO与KVC

    KVO 什么是KVO? KVO 是 Key-value observing(键值观察)的缩写。 KVO是Objec...

  • 可能碰到的iOS笔试面试题(7)--KVO-KVC

    KVC-KVO KVC的底层实现? KVO的底层实现? 什么是KVO和KVC? KVO的缺陷? KVO是一个对象能...

网友评论

      本文标题:KVO

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