博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS学习和总结KVO
阅读量:7065 次
发布时间:2019-06-28

本文共 3609 字,大约阅读时间需要 12 分钟。

关于KVO,估计很多同学对KVO一样是很模糊的,都听到大家在说,面试会问,但是在开发中很少使用到,一般使用到的也是某个组件中封装使用,而这个封装又不是交由自己来完成,因此还是很模糊。

现在想来,似乎我也不清楚了,到底KVO是什么,怎么用,又会在哪种场景中使用。带着疑问,让我们一起来学习学习吧

1、什么是KVO?

KVO其实就是Key-Value-Observer,也就是键值观察者,是基于KVC机制实现的另一种模式。也许有不少同学用过SVPullToRefresh或者MJRefresh刷新组件,都使用了KVO来实现。

2、使用场景会使用KVO呢?

似乎使用场景并不多,NSOperationQueue中使用了KVO,当NSOperation对象状态变化(finished,canceled等)时,观察者可以知道变化,从而做出相应的处理(移除已完成的等等);

3、怎么实现KVO?

现在假设需求:某个学生成绩变化时,让观察者知道

让我们建立一个学生实体类,实现文件什么也不用动:

@interface HYBStudent : NSObject@property (nonatomic, copy) NSString *studentName;@property (nonatomic, assign) CGFloat grade;@end

下面viewcontroller中实例化一个学生实体,让controller成为学生实体的观察者,这里是使用一对一的观察模式,看看打印结果:

#import "ViewController.h"#import "HYBStudent.h"@interface ViewController ()@property (nonatomic, strong) HYBStudent *student;@end@implementation ViewController- (void)viewDidLoad {  [super viewDidLoad];  self.student = [[HYBStudent alloc] init];  self.student.studentName = @"李四";  self.student.grade = 90.f;  // add observer to the student  [self.student addObserver:self forKeyPath:@"grade" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial context:nil];  [self performSelector:@selector(changeGrade) withObject:nil afterDelay:4.0];}- (void)changeGrade {  self.student.grade = 100.0f;}- (void)observeValueForKeyPath:(nullable NSString *)keyPath                      ofObject:(nullable id)object                        change:(nullable NSDictionary *)change                       context:(nullable void *)context {  if ([keyPath isEqualToString:@"grade"]) {    NSLog(@"student %@'s grade is %f'",          self.student.studentName, self.student.grade);  }}- (void)dealloc {  // Don't forget to remove observer  [self.student removeObserver:self forKeyPath:@"grade" context:nil];}@end

打印结果如下:

2015-08-28 16:18:00.537 KVODEMO[1281:476192] student 李四's grade is 90.000000'2015-08-28 16:18:04.539 KVODEMO[1281:476192] student 李四's grade is 100.000000'

下面我们来看看另一种场景:一对多

需求如下:学生李四的成绩变化时,要通知他的同学张三

实现如下,在HYBStudent.m文件中实现如下方法:

- (void)observeValueForKeyPath:(nullable NSString *)keyPath                      ofObject:(nullable id)object                        change:(nullable NSDictionary *)change                       context:(nullable void *)context {  if ([keyPath isEqualToString:@"grade"]) {      NSLog(@"张三的同学成绩发生了变化: %@'s grade is %f'",            ((HYBStudent *)object).studentName, ((HYBStudent *)object).grade);  }}

然后在viewDidLoad的最后追加如下代码,其它不变:

// 再次实例化一个学生实体,作为student的同学  self.zhangStudent = [[HYBStudent alloc] init];  self.zhangStudent.studentName = @"张三";  self.zhangStudent.grade = 59;  [self.student addObserver:self.zhangStudent                 forKeyPath:@"grade"                    options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionInitial                    context:nil];

看看打印结果 :

2015-08-28 16:43:51.234 KVODEMO[1317:480175] student 李四's grade is 90.000000'2015-08-28 16:43:51.235 KVODEMO[1317:480175] 张三的同学成绩发生了变化: 李四's grade is 90.000000'2015-08-28 16:43:55.236 KVODEMO[1317:480175] 张三的同学成绩发生了变化: 李四's grade is 100.000000'2015-08-28 16:43:55.237 KVODEMO[1317:480175] student 李四's grade is 100.000000'

总结:1、谁成为观察者,谁就得实现

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

这个API,以便在值发生变化时,做相应的处理,如果没有实现此API,会抛出异常,导致crash。2、添加观察者与移除观察者是成对出现的,一定要记得移除

// Don't forget to remove observer  [self.student removeObserver:self forKeyPath:@"grade" context:nil];  [self.student removeObserver:self.zhangStudent forKeyPath:@"grade" context:nil];

转载地址:http://uusll.baihongyu.com/

你可能感兴趣的文章
恢复误删除的ESXi服务器存储VMFS卷
查看>>
SFB 项目经验-22-如何查看存储的管理IP地址
查看>>
libevent入门教程:Echo Server based on libevent
查看>>
.NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
查看>>
一次服务器CPU占用率高的定位分析
查看>>
安装office2007 1706错误
查看>>
crontab中执行多条命令
查看>>
25 JavaScript的幻灯片用于在Web布局的精彩案例
查看>>
用C语言写的迅雷看看XV文件提取器及C语言源代码
查看>>
ccpuid:CPUID信息模块 V1.01版,支持GCC(兼容32位或64位的Windows/Linux)
查看>>
用dom4j操作XML文档(收集)
查看>>
WinForm实例源代码下载
查看>>
hdu 1829 A Bug's Life(并查集)
查看>>
每日英语:Chinese Writer Wins Literature Nobel
查看>>
java中三种主流数据库数据库(sqlserver,db2,oracle)的jdbc连接总结
查看>>
Oracle Apps AutoConfig
查看>>
[leetcode]Flatten Binary Tree to Linked List
查看>>
css颜色代码大全:(网页设计师和平面设计师常用)
查看>>
boost 1.52在windows下的配置
查看>>
素材锦囊——50个高质量的 PSD 素材免费下载《上篇》
查看>>