KVO的使用一
概述
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的使用一的更多相关文章
- iOS---观察者模式之--->KVO
文章结构如下: Why? (为什么要用KVO) What? (KVO是什么) How? ( KVO怎么用) More (更多细节) 原理 自己实现KVO 在我的上一篇文章浅谈 iOS Notifica ...
- Objective-C之KVC、KVO
1,KVC(键值编码) Key Value Coding 1.1在C#中,可以通过字符串反射来获取对象,从而对对象的属性进行读写,Object-C中有同样的实现,通过字符串(属性名词)对对象的属性进 ...
- OS 如何选择delegate、notification、KVO?
原文链接:http://blog.csdn.net/dqjyong/article/details/7685933 前面分别讲了delegate.notification和KVO的实现原理,以及实际使 ...
- KVC 和 KVO
KVC 键值编码 全称是Key-value coding,翻译成键值编码.它提供了一种使用字符串而不是访问器方法去访问一个对象实例变量的机制. 1.通过key(成员变量的名称)设置 ...
- 11. KVC And KVO
1. KVC And KVO 的认识 KVC/KVO是观察者模式的一种实现 KVC全称是Key-value coding,翻译成键值编码.顾名思义,在某种程度上跟map的关系匪浅.它提供了一种使用 ...
- KVO __ 浅谈
KVO :Key-Value Observing 它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了. ...
- iOS开发系列--Objective-C之KVC、KVO
概述 由于ObjC主要基于Smalltalk进行设计,因此它有很多类似于Ruby.Python的动态特性,例如动态类型.动态加载.动态绑定等.今天我们着重介绍ObjC中的键值编码(KVC).键值监听( ...
- delegate、notification、KVO场景差别
delegate: 编译器会给出没有实现代理方法的警告 一对一 使用weak而不是assign,或者vc消失时置为nil 可以传递参数,还可以接收返回值 notification: 编译期无法排错 一 ...
- IOS学习之初识KVO
什么是KVO? KVO(Key-Value Observing)键值观察,是一种通过对对象的某一个属性添加观察者,一旦这个属性值发生变化,就会通知当前观察者的一种机制. 该如何使用? 1.注册,指定被 ...
- KVC & KVO
KVC和KVO看上去又是两个挺牛的单词简写,KVC是Key-Value Coding的简写,是键值编码的意思.KVO是Key-Value Observing的简写,是键值观察的意思.那么我们能拿KV ...
随机推荐
- chrome 浏览器之下载管理器插件
chrome默认下载器实在是不招人待见,下面插件是一个非常不错的选择: 名称:Chrono下载管理器 插件地址:https://chrome.google.com/webstore/detail/ch ...
- shell脚本监控网站状态
shell脚本监控网站状态 #!/bin/sh date=`date +"%Y%m%d-%H%M"` title="status" contentFail=&q ...
- ThinkPHP3.2.3框架下接入阿里云短信服务接口实现:注册登录
首先介绍下短信注册登录流程: 注册页面点击获取手机号验证码按钮,用jquery的click事件POST或GET方法把手机号发送到后台控制器: 后台控制器创建函数,收到手机号后生成随机码,例如:6位的随 ...
- 用vue制作饿了么首页(1)
无论是静态网页还是动态交互网页,实现原则是将他们分块,然后各个击破. 很明显的饿了么首页分为三个部分(组件), 上面的头部(商家信息), 中间路由 购物车 每部分先占住自己位置,然后挨个将这三部分分别 ...
- 【node】node连接mongodb操作数据库
1.下载第三方模块mongodb cnpm install mongodb --save 2.检测是否连接成功 1.引入第三方模块mongodb并创建一个客户端 const MongoClient = ...
- HTML01
1.什么是HTML?(Hyper Text Markup Language:超文本标记语言) 超文本:功能比普通文本更加强大 标记语言:使用一组标签对内容进行描述的一门语言(它不是编程语言) 2.为什 ...
- Luogu 1309 - 瑞士轮 - [归并排序]
题目链接:https://www.luogu.org/problemnew/show/P1309 题解: 每次比赛前,每个人都是按照分数降序排好的,那么比赛完后,将选手按输赢分成两组,顺序依然按照原顺 ...
- Restful API设计规范
理解RESTful架构 Restful API设计指南 理解RESTful架构 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式 ...
- listview添加数据
1. 添加数据: ListView1.ViewStyle:=vsReport; ListView1.Columns.Add; ListView1.Columns[0].Caption:='aaaa'; ...
- Emmet.vim 教程
Emmet.vim 教程 May 5, 2012 目录 1 下载 Emmet.vim 2 安装 Emmet.vim 3 使用 Emmet.vim 4 余话 Emmet 项目原先叫 Zen Coding ...