首页 > 学院 > 开发设计 > 正文

KVO -- 键值监听

2019-11-06 09:59:28
字体:
来源:转载
供稿:网友

1、KVO简单介绍

KVO(Key Value Observing)键值监听,属于苹果官方API。

作用:iOS开发中通常将代码分为数据模型和试图控件,数据模型维护程序的状态数据,试图控件将数据模型中的数据展示出来。而KVO能监听当数据模型发生改变时,及时通知试图控件动态将改变的数据显示出来。 注意:只有通过setter方法改变的属性值,才能被KVO监听到,才能触发observeValueForKeyPath:ofObject:change:context:回调方法

KVO的使用: 1.注册需要观察的对象的属性addObserver:forKeyPath:options:context: 2.实现observeValueForKeyPath:ofObject:change:context:方法,这个方法当观察的属性变化时会自动调用 3.取消注册观察removeObserver:forKeyPath:context:

- (void)viewDidLoad { [super viewDidLoad]; self.stu = [[Student alloc] init]; // 添加观察者 // observer:观察者 keyPath:想要监听的属性名 options:枚举 回调时可以获取改变前后的值 content:上下文 [self.stu addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];}// 属性发生改变时的回调- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{ // keyPath:属性名 change:改变前后的属性值 content:上下文 NSLog(@"%@", change[@"new"]);}// 释放观察者- (void)dealloc{ [self.stu removeObserver:self forKeyPath:@"age"];}

2、KVO底层实现(记录自小马哥视频)

当KVO被触发时 1>首先系统会自动创建NSKVONotifying_Student类(这里以Student为例), NSKVONotifying_Student是Student的子类 2>修改当前对象(student)的isa指针,指向NSKVONotifying_Student 3>只要调用对象的setter方法,就会调用NSKVONotifying_Student的setter方法 4>重写NSKVONotifying_Student的setter方法:[super set:],通知观察者对象的属性值发生改变

下面我们来自己实现KVO,以便更好的理解KVO的底层实现过程。 1>系统KVO是基于NSObject,所以我们可以创建一个NSObject的分类NSObject+KVO NSObject+KVO.h文件

#import <Foundation/Foundation.h>@interface NSObject (KVO)- (void)zhaoName_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;@end

NSObject+KVO.m文件

#import "NSObject+KVO.h"#import <objc/runtime.h>#import "ZKVONotifying_Student.h"@implementation NSObject (KVO)- (void)zhaoName_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context{ // 修改isa指针 本质是改变当前对象的类名 object_setClass(self, [ZKVONotifying_Student class]); // 保存观察者 即动态添加属性 // object:给哪个对象添加属性 key:属性名 value:属性值 policy:关联策略 objc_setAssociatedObject(self, @"observer", observer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);}@end

2>重写子类NSKVONotifying_Student的setter方法,通知观察者 NSKVONotifying_Student.m文件

#import "ZKVONotifying_Student.h"#import <objc/runtime.h>@implementation ZKVONotifying_Student- (void)setAge:(NSUInteger)age{ [super setAge:age]; // 获取保存的观察者 id observer = objc_getAssociatedObject(self, @"observer"); // 通知 // 注意这里change传nil,则在回调时change为空 [observer observeValueForKeyPath:@"age" ofObject:self change:nil context:nil];}@end

这样调用我们自己实现的KVO也能实现属性改变的监听

[self.stu zhaoName_addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionNew context:nil];
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表