概述

KVO即Key-Value Observing,它允许一个对象被另一个对象在改变指定的属性值后进行通知。iOS中的应用场景很多,比如model的值发生变化,controller里对model进行监听从而改变view。便于对KVO有更好地理解,可以先理解KVC:苹果官方KVC文档。最直接有效的学习方法是官方文档:KVO官方文档,这个文档还有日文版,很是诧异!!!

原理

系统为被观察者生成一个子类,命名方式NSKVONotyfing_类名,当监听的键值发生改变时,系统调用重写的子类set方法对该键进行赋值,并在内部加一个消息传递,让观察者去接受值的变化并可以进行相应地操作。

实际运用

KVO的实现采用了观察者模式,使用大致流程是先注册观察者被观察者等,然后改变要观察的键值,最后在观察者的消息接收方法中根据改变后的键值进行相应的处理。

iOS在NSObject、NSArray、NSOrderSet、NSSet中都加入了实现KVO的分类,而我们平时使用的大部分对象都是这些类的子类,所以系统KVO能够满足大部分需求。

  • 使用KVO要先进行注册,确定观察者、被观察者及要监听的值对象。使用分类NSKeyValueObserverRegistration的方法进行注册。

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

  • observer参数是接收消息的对象
  • keyPath是要观察的键名
  • options是一个枚举,包含四个枚举值:

NSKeyValueObservingOptionNew:接收消息方法的change字典中有新改变的值。

NSKeyValueObservingOptionOld:接收消息方法的change字典中有改变前一次的值。

NSKeyValueObservingOptionInitial:立即向接收消息方法发送通知,简言之就是你的注册方法可能还没执行完,已经接收到消息了。

NSKeyValueObservingOptionPrior:键值改变前后都会发送消息。

  • context是用来区分相同被观察者的不同键值或者不同被观察者同一或不同键值的标识,防止混淆。

知晓了注册方法,我们先声明一个Person类,添加两个属性name和age。在ViewController里的类扩展中添加一个Person类型的属性person,viewDidLoad方法里添加注册方法。

- (void)viewDidLoad {

[super viewDidLoad];

self.person = [[Person alloc] init];

[self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNewcontext:nil];

NSLog(@"观察者注册完毕");

}

  • 接下来改变监听的键值,触发系统动态添加的子类的setName方法,改变键值后通知观察者接收消息。添加一个触摸屏幕事件,在里面改变name的值

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

self.person.name = @"小明";

}

  • 现在使用观察者的接收消息方法,处理键值变化后的情况。

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

  • keyPath是观察的键的名称。
  • object是被观察对象。
  • change是一个变化前后值的字典,包括改变前后的值等,和注册方法的options有关。
  • context是在注册时用来区分判定键的标识。

我们在该方法中实现一个NSLog方法,打印上述内容信息。NSKeyValueChangeKey是一个封装的const,包括NSKeyValueChangeKindKey、NSKeyValueChangeNewKey、NSKeyValueChangeOldKey、NSKeyValueChangeIndexesKey和NSKeyValueChangeNotificationIsPriorKey。

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

NSLog(@"监听到%@对象的%@属性的改变为%@",[object class],keyPath,[change objectForKey:NSKeyValueChangeNewKey]);

}

  • 打印结果:

从结果看出来,消息接收方法收到Person的name变化。

以上就是KVO的简单实现过程。

 

KVO的使用一的更多相关文章

  1. iOS---观察者模式之--->KVO

    文章结构如下: Why? (为什么要用KVO) What? (KVO是什么) How? ( KVO怎么用) More (更多细节) 原理 自己实现KVO 在我的上一篇文章浅谈 iOS Notifica ...

  2. Objective-C之KVC、KVO

    1,KVC(键值编码)  Key Value Coding 1.1在C#中,可以通过字符串反射来获取对象,从而对对象的属性进行读写,Object-C中有同样的实现,通过字符串(属性名词)对对象的属性进 ...

  3. OS 如何选择delegate、notification、KVO?

    原文链接:http://blog.csdn.net/dqjyong/article/details/7685933 前面分别讲了delegate.notification和KVO的实现原理,以及实际使 ...

  4. KVC 和 KVO

    KVC 键值编码    全称是Key-value coding,翻译成键值编码.它提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制.        1.通过key(成员变量的名称)设置 ...

  5. 11. KVC And KVO

    1. KVC And KVO  的认识 KVC/KVO是观察者模式的一种实现  KVC全称是Key-value coding,翻译成键值编码.顾名思义,在某种程度上跟map的关系匪浅.它提供了一种使用 ...

  6. KVO __ 浅谈

    KVO :Key-Value Observing 它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了. ...

  7. iOS开发系列--Objective-C之KVC、KVO

    概述 由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby.Python的动态特性,例如动态类型.动态加载.动态绑定等.今天我们着重介绍ObjC中的键值编码(KVC).键值监听( ...

  8. delegate、notification、KVO场景差别

    delegate: 编译器会给出没有实现代理方法的警告 一对一 使用weak而不是assign,或者vc消失时置为nil 可以传递参数,还可以接收返回值 notification: 编译期无法排错 一 ...

  9. IOS学习之初识KVO

    什么是KVO? KVO(Key-Value Observing)键值观察,是一种通过对对象的某一个属性添加观察者,一旦这个属性值发生变化,就会通知当前观察者的一种机制. 该如何使用? 1.注册,指定被 ...

  10. KVC & KVO

    KVC和KVO看上去又是两个挺牛的单词简写,KVC是Key-Value Coding的简写,是键值编码的意思.KVO是Key-Value  Observing的简写,是键值观察的意思.那么我们能拿KV ...

随机推荐

  1. selenium 操作过程中,元素标红高亮的两种实现方式

    在使用selenium时,动作元素标红高亮,在定位问题时相当好用,有以下二种方法可以实现 一.使用js将元素属性修改 这也是网上大部分的实现方式,但有时候会有点小问题,代码如下: 只写其实某一段函数 ...

  2. Spring MVC 知识点整理

    extend:http://www.jianshu.com/p/bef0e52067d2 1. Redis 存储方式 Redis存储机制分成两种Snapshot 和 AOF.无论是那种机制,Redis ...

  3. IOS如何安装ipa文件

    https://www.i4.cn/pro_ios.html#jiaocheng 用电脑下载 爱思助手PC端 然后电脑连接 苹果手机, 用 安装的 爱思助手PC端 软件 安装 “爱思助手移动端” 下载 ...

  4. springmvc中为我们做了什么

    这应该是每个使用框架的人应该自问的.这就要从没有使用框架时说.在没用框架开发web应用时,自己是怎么开发的,就是写servlet,jsp. 使用springmvc后,使用Controller注解,其实 ...

  5. 9 ArcGIS Server 性能优化

    1.系统性能影响因子 地图.服务类型.数据源.客户端技术.CPU.数据结构.网络.内存.存储.部署.架构.服务接口.SDE等. 2.ArcGIS Server性能优化 数据结构与数据源:数据结构(矢量 ...

  6. 用js实现二维数组的旋转

    我最近因为做了几个小游戏,用到了二维数组,其中有需求将这个二维数组正翻转 90°,-90°,180°. 本人是笨人,写下了存起来. 定义的基本二位数组渲染出来是这种效果. 现在想实现的结果是下面的效果 ...

  7. python——shopping car

    # _Author:huang# date: 2017/11/26 # 简单的购物车程序money = input("money:") product_list = [ (&quo ...

  8. Python学习之旅(七)

    Python基础知识(6):基本数据类型之列表 在Python中,最基本的数据结构是序列.序列中的每个元素被分配一个序号——即元素的位置,也称为索引.第一个索引从0开始,如果要从右边开始,序列中的最后 ...

  9. 在 C# 中使用文件名启动应用程序

     本文演示了如何启动与某一给定文档扩展名或文件类型关联的应用程序而又无须知道该关联应用程序的名称或位置.例如,您可以用一个与 .bmp 文件扩展名关联的应用程序启动 Arcade.bmp 文件,多 ...

  10. C和C指针小记(十三)-数组

    1.1 一维数组 一维数组的声明: int a[10]; 这里a就是一个数组. 数组a的类型就是一个指向整型的常量指针. 但是数组和指针是**不相同**的. **数组具有特定数量的元素,而指针只是一个 ...