IOS学习和总结KVO

简介:

关于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];
目录
相关文章
|
5月前
|
前端开发 开发工具 Swift
学习iOS开发的准备
准备学习iOS开发?确保有Mac和最新Xcode,先学好编程基础特别是Swift。利用Apple官方文档、在线课程和书籍作为资源。熟悉Xcode及Git,通过实践项目和开源代码积累经验。深研架构模式、核心框架和优化技巧。加入开发者社区,关注行业动态,持续学习。
51 1
|
安全 前端开发 Android开发
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
鸿蒙开发学习是一项探索性的工作,旨在开发一个全场景分布式操作系统,覆盖所有设备,让消费者能够更方便、更直观地使用各种设备。
691 6
鸿蒙开发|鸿蒙系统的介绍(为什么要学习鸿蒙开发|鸿蒙系统的官方定义|鸿蒙和安卓、ios的对比)
|
iOS开发
iOS UIKit Dynamics Demo 学习地址列表
iOS UIKit Dynamics Demo 学习地址列表
52 0
|
XML JSON 编解码
IM通讯协议专题学习(九):手把手教你如何在iOS上从零使用Protobuf
接上篇《金蝶随手记团队的Protobuf应用实践(原理篇)》,本文将以iOS端的Objective-C代码为例,图文并茂地向您菔救绾卧趇OS工程中快速使用Protobuf,希望对你有帮助。
176 0
IM通讯协议专题学习(九):手把手教你如何在iOS上从零使用Protobuf
|
iOS开发
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
150 0
iOS开发 - 写一个刷新的控件(未封装,适合新手学习,查看原理)
|
存储 Unix 编译器
|
存储 算法 iOS开发
|
存储 缓存 算法
iOS底层学习——对象初始化探索
iOS底层学习——对象初始化探索
|
物联网 Android开发 iOS开发
iOS开发 - 蓝牙学习的总结
iOS开发 - 蓝牙学习的总结
187 0
|
安全 iOS开发 开发者
iOS 6版本与之前版本差异总结
iOS 6版本与之前版本差异总结
130 0

相关课程

更多