文档章节

IOS中的KVO机制详解

哪一种黑
 哪一种黑
发布于 2016/02/29 20:50
字数 1000
阅读 113
收藏 1

ios开发有多种设计模式,其中有一种就叫做观察者模式,即Key Value Observing(简称KVO)

KVO是Object -C中原声支持的一种机制.


C、KVO 实现原理
当对一个对象添加观察者,被观察对象的属性值发生变化时,观察者会得到通知,并对变化做出相应的处理。
D、KVO 的特性
1. 支持多个观察者观察同一属性,也支持一个观察者监听不同属性。
2. 利用它可以很容易地实现视图和数据模型的分离,当数据模型的属性值改变之后,作为监听器的视图就会被激发,并回调监听器自身的监听方法。
3. 对于KVC的基本的方法都定义在 NSKeyValueCoding 的非正式协议中,并且NSObject默认实现了该协议。相对的,在ObjC中要实现KVO则必须实现NSKeyValueObServing 协议,不过 NSObject 已经实现了该协议,因此几乎所有的ObjC对象都可以使用KVO。
E、KVO在 ObjC 中的用法
1. 注册观察者:
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
2. 实现回调监听方法:
- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSString*, id> *)change context:(nullable void *)context;
3. 移除观察者:
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
F、苹果官方对于KVO的解释及本人翻译
Key-Value Observing Implementation Details
翻译: KVO 实现详解
Automatic key-value observing is implemented using a technique called isa-swizzling.
翻译: KVO 是通过使用 isa-swizzling 技术实现的。
The isa pointer, as the name suggests, points to the object's class which maintains a dispatch table. This dispatch table essentially contains pointers to the methods the class implements, among other data.
翻译: 这个 isa 指针,顾名思义,指向该对象的类,这个类包含了一个派遣信息表。这个派遣信息表本质上包含很多指针,这些指针指向了该类实现的所有方法。
When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class. As a result the value of the isa pointer does not necessarily reflect the actual class of the instance.
翻译: 当一个对象的属性被注册了观察者时,指向被观察对象的 isa 指针就被修改了,修改为指向了一个中间类而不是原来的类。其结果是,该 isa 指针不一定反映的就是该实例(被观察者对象)的真实类。
You should never rely on the isa pointer to determine class membership. Instead, you should use the class method to determine the class of an object instance.
翻译: 你永远都不要依赖 isa 指针去确定类成员,你应该使用类方法来确定类的实例对象。
G、KVO 的底层实现:
1. KVO 的底层实现是通过Objective-C强大的运行时(runtime)实现的。
2. 当你第一次观察一个对象object时,runtime 会动态地创建一个继承自该对象object所属类的子类,类名格式为为NSKVONotifying_[subclass名],同时保存注册观察者方法中的所有参数,包括监听者、路径、枚举、携带参数等。
3. 这个新创建的子类重写了所有被观察属性的 setter 方法,并且在内部给观察者发送通知,通知所有观察对象值的更改。
4. 最后把这个对象object的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么类型的 ) 指向这个新创建的子类,此时这个被观察的对象 object 就神奇地变成了新的子类的实例。

H、Demo验证:
@interface People : NSObject
@property (nonatomic,strong) NSString *name;
@end
#import "ViewController.h"
#import "People.h"
@interface ViewController ()
@property (nonatomic,strong) People *p;
@end
@implementation ViewController
- (void)viewDidLoad {  
    [super viewDidLoad];    
    People *person = [[People alloc] init];    
    person.name = @"花无缺";    
    self.p = person;    
        // 添加观察者
    [person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];    
    person.name = @"小鱼儿";
}
// 实现监听方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{    
    NSLog(@"%@",change);
}
// 移除监听者
-(void)dealloc{    
    [self.p removeObserver:self forKeyPath:@"name"];
}
@end



© 著作权归作者所有

共有 人打赏支持
哪一种黑
粉丝 8
博文 11
码字总数 9722
作品 0
昌平
私信 提问
iphone开发技术要学习的内容

一.iOS基础   1 开发环境搭建以及IOS组件、框架的概要介绍。   2 mac操作系统与iOS操作系统   3 xcode IDE开发环境的初始   二.C语言基础   1数据类型、表达式与控制流程语句   ...

和谐中原植物酒
2015/08/24
149
2
iOS高仿QQ侧滑控件、下载框架、动画效果、扫一扫、颜色变化、K线图等源码

iOS精选源码 仿京东"加入购物车"转场动画(http://www.code4app.com/thread-28162-1-1.html) ColorTool(颜色转换)(http://www.code4app.com/thread-29256-1-1.html) Swift 专业版K线(http://w......

sunnyaigd
2018/04/17
0
0
2018 iOS 面试题大全(补充完整版)

原文地址:2018 iOS 面试题大全 由于原作者并没有继续更新,这里我转过来继续更新下 这个栏目将持续更新--请iOS的小伙伴关注! 1、iOS 应用导航模式有哪些? 2、iOS 中持久化方式有哪些? 3、...

Theendisthebegi
2018/11/15
0
0
iOS与JS交互之UIWebView-JSExport协议

级别:★★☆☆☆ 标签:「iOS与JS交互」「UIWebView与JS交互」「JSExport」 作者: Xs·H 审校: QiShare团队 先解释下标题:“iOS与JS交互”。iOS指原生代码(文章只有示例),JS指前端(不...

QiShare
2018/08/31
0
0
iphone开发资源汇总

iphone开发资源汇总 如何用Facebook graphic api上传视频: http://developers.facebook.com/blog/post/532/ Keychain保存数据封装: https://github.com/carlbrown/PDKeychainBindingsContr......

长平狐
2012/10/25
232
0

没有更多内容

加载失败,请刷新页面

加载更多

安卓constraintLayout中app:srcCompat设置的图片显示不出来

使用 app:srcCompat 的时候 引入的图片显示不出来的解决方案 首先查看的你的Activity 继承的是那个Activity 如果是继承AppcompatActivity 使用 ImageView的 app:srcCompat 是没有问题的 如果...

雨焰
41分钟前
1
0
MySQL mysqldump数据导出详解

MySQL mysqldump数据导出详解 2016-04-07 11:14 by pursuer.chen, 114348 阅读, 0 评论, 收藏, 编辑 介绍 在日常维护工作当中经常会需要对数据进行导出操作,而mysqldump是导出数据过程中使用...

linjin200
41分钟前
0
0
Lucene 检索时的步骤

用户输入查询语句:lucene AND learned NOT hadoop 搜索主要分为以下几步 第一步、对查询语句进行词法分析,语法分析,及语言处理 词法分析主要用来识别单词和关键字 语法分析主要是根据查询...

kdy1994
41分钟前
2
0
Gradle Implementation vs API configuration

注: 可以把 Implementation理解为java类的private, 使用Implementation则外部依赖本库的代码引用不到本库Implementation的代码, 也就是降低依赖树的层级, 这样就可以避免外部代码编译时候, 导...

SuShine
45分钟前
2
0
pdf安卓手机适配以及ie的兼容 以及隐藏掉下载打印按钮的方式

这是我目前遇到pdf方面最多的问题。 在百度上搜了很多答案,结果都是建议使用插件。而目前百度能搜的插件基本上都是有缺陷的。自己测试了很多插件。最后使用了pdf.js这个插件。这个插件目前完...

流年那么伤
51分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部