KVO 开发详情
目录
概念
应用KVO的3个步骤
关联属性的KVO
手动管理KVO通知
一、概念
KVO全称是 Key-Value Observing ,是OC的一种消息发送机制。这个机制是指:假设将B对象注册为A对象的观察者,当A对象的属性发生改变时就会通知它自己的所有观察者包括对象B在内。
KVO一般用于Controller与Model之间的通信。常见的做法是把Controller注册为Model的观察者,当model改变时Controller就会收到通知并根据新的model来更新View。
KVO是基于KVC技术的,所以为了理解KVO你必须先了解KVC(还不了解的请移步)。
需要注意的是,只有两个方式改变对象的属性才会触发KVO通知
1.通过KVC方法改变(setValue:forKey,setValue:forKeyPath)
2.通过setter函数(.操作符会调用setter)
当然你也可以手动管理KVO通知,我们在下面将会讲到
二、应用KVO的3个步骤
- 为被观察者注册一个观察者
- 观察者接收属性改变的通知
- 移除观察者
1.注册观察者
//这句代码的意思是 self.observing 观察 self.observed的age属性
[self.observed addObserver:self.observing forKeyPath:@"age" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
2.接收通知
在观察者类实现下面方法,当被观察的对象的属性改变时KVO就会调用这个方法。
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
NSLog(@"%@ : [%@] => [%@]",keyPath,[change valueForKey:NSKeyValueChangeOldKey],[change valueForKey:NSKeyValueChangeNewKey]);
}
3.移除观察者
因为注册观察者时,被观察者就持有观察者的强引用,这有这样才能在属性改变时通知观察者。
[self.observed removeObserver:self.observing forKeyPath:@"age"];
我可以这样有下面代码改变属性,触发KVO通知
// setter
[self.observed setAge:@];
// kvc
[self.observed setValue:@ forKey:@"age"];
如果不出意外应该会输出如果log
age : [] => []
age : [] => []
三、关联属性的KVO
关联的属性分为两种情况,一对多,多对多
多对多情况,我们只能通过手动触发KVO等方式来处理
下面我们来介绍一对多的情况。
假设Person类有一个readonly的属性 fullName,这个fullName有firstName和lastName组成,下面是fullName的getter函数
-(NSString *)fullName{
return [NSString stringWithFormat:@"%@ %@",self.firstName,_lastName];
}
我们希望当改变firstName或者lastName时可以触发fullName的kvo通知以便告诉其他人,他人只要观察fullName属性就可以了而不需要分别观察firstName跟lastName。
我们可以有如下函数之一来告诉fullName与fristName、lastName的关联关系
// 单个对象的属性 1
+(NSSet *)keyPathsForValuesAffectingFullName{
return [NSSet setWithArray:@[@"firstName",@"lastName"]];
}
// 单个对象的属性 2
+(NSSet<NSString *> *)keyPathsForValuesAffectingValueForKey:(NSString *)key{
NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
if ([key isEqualToString:@"fullName"]) {
NSArray *affectingKeys = @[@"lastName", @"firstName"];
keyPaths = [keyPaths setByAddingObjectsFromArray:affectingKeys];
}
return keyPaths;
}
四、手动管理KVO通知
普通的对象之所以拥有KVO的功能是因为我们的对象都是继承自NSObject类的。
NSObject帮我实现了一些函数, KVO在适当的时候通过调用这些函数来完成KVO功能。
其中包过下面两个函数
-(void)willChangeValueForKey:(NSString *)key;
-(void)didChangeValueForKey:(NSString *)key;
我们正式通过自己调用这两个函数来控制KVO的通知的发送,当我们想手动触发age属性的KVO通知时可以这样写:
[self willChangeValueForKey:@"age"];
_age = ;
[self didChangeValueForKey:@"age"];
当然,最后你得告诉oc说你自己来管理KVO通知
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey {
if ([theKey isEqualToString:@"age"]) {
return NO;
}
}
KVO 开发详情的更多相关文章
- ARC中KVO开发注意
1 在ARC 中 KVO开发 添加监听和去掉监听必需 一一匹配,不要有过的去掉监听否则会有可能导致对象无法释放. 例如,在一个viewcontroller中添加webview 并监听webview的c ...
- objective-c runtime 开发详情
目录 概述 对象与类的实质 id与class 继承关系与isa 总结 C函数创建一个OC类 OC类与runtime NSObjectProtocol NSObject NSProxy 一.概述 Obj ...
- iOS 定时器开发详情
目录 概述 NSTimer performSelector GCD timer CADisplayLink 一.概述 在平时的开发任务中,定时器是我们常用的技术.这一节我们来学习iOS怎么使用定时器. ...
- KVC 开发详情
目录 概述 KVC基本技术 KVC访问函数 KVC搜索顺序 KVC集合操作 一.概述 kvc全名是Key-value coding,kvc是一种通过字符串间接的访问oc对象的属性的一种技术. 一个oc ...
- GCD 开发详情
目录 一.简介 二.dispatch Queue - 队列 三.dispatch Groups - 组 四.dispatch Semaphores - 信号量 五.dispatch Barriers ...
- 如何开发Android Wear应用程序
Android Wear是连接安卓手机和可穿戴产品的一个平台.自从今年上半年发布以来,Android Wear获得了大量关注,既有来自消费者的关注,也有来自开发商的关注,后者希望自己的应用程序已经准备 ...
- 微信小程序开发-概述
微信小程序开发-概述 一.小程序申请&APPID 登录微信平台申请成为小程序开发者,小程序不可直接使用服务号或订阅号的AppID,需要登录微信公众平台管理后台,在网站的"设置&quo ...
- jeecms v9开发资料
开发文档 . 系统架构概述 本系统核心架构为 FreeMarker+hibernate+Spirng 的 mvc 分层架构. 1.1 分层架构模型 img 1.2 数据流转模型 (前端) img . ...
- 教你如何开发一个完败Miracast的投屏新功能
手机与电视,是陪伴在我们生活最常见,陪伴最长久的智能设备.迅猛发展的移动终端与通信技术,赋予了手机更广阔多元的应用生态,大屏电视则以大视野和震撼影音,弥补了手里方寸带来的视觉局限.而今,手机的延伸 ...
随机推荐
- QQ群认证 人数再度扩容 权限随之升级
群排名,得资源得天;之于排名,群容量有杠杆意义. 而今,流量分散,打法完全无法集中,全平台战略,越发凸显.QQ群,已是必争之地. 去年,Q群霸屏春天,一切那么顺其自然;而今,除了拼资源,还是拼资源.除 ...
- git上下载的thinkphp框架报错解决方法
git上下载的thinkphp5框架使用.gitignore没上传依赖,需要通过composer进行下载依赖,使用composer install或者composer update即可解决.
- hadoop生态搭建(3节点)-06.hbase配置
# http://archive.apache.org/dist/hbase/1.2.4/ # ==================================================== ...
- 【Hbase一】基础
此笔记仅用于作者记录复习使用,如有错误地方欢迎留言指正,作者感激不尽,如有转载请指明出处 Hbase基础 Hbase基础 Hbase定义 行存储 v s 列存储 Hbase数据模型 Hbase物理模型 ...
- Python系列8之socket
目录 socket 简单的聊天机器人 简单的ftp上传 粘包问题的解决 一. socket模块 socket,俗称套接字,其实就是一个ip地址和端口的组合.类似于这样的形式(ip, port),其中 ...
- Java+Selenium3方法篇24-单选和多选按钮操作
Java+Selenium3方法篇24-单选和多选按钮操作 本篇介绍 webdriver处理前端单选按钮的操作.单选按钮一般叫raido button,就像我们在电子版的单选答题过程一样,单选只能点击 ...
- n点游戏
n点游戏 24点游戏是非常经典而简单的小游戏,从一堆扑克牌中抽取4张,向其中添加运算符号并使其运行结果恰等于24,这叫作24点游戏. 现在我们不再是组合24,而是组合出给定的数字n,但要求只可以利用任 ...
- Python3 time模块&datetime模块&random模块
''' time模块 ''' # import time # print(help(time)) # help()提供帮助 # print(time.time()) # 1970年开始到现在的秒数(时 ...
- WPF把CheckBox的文字放到左边,开关在右边
原文:WPF把CheckBox的文字放到左边,开关在右边 效果 实现 这篇文章给了一个不错的参考方案. http://www.codeproject.com/Articles/19141/WPF-Ch ...
- 转MySQL详解--索引
写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...