文档章节

IOS中的KVO机制详解

哪一种黑
 哪一种黑
发布于 2016/02/29 20:50
字数 1000
阅读 109
收藏 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
昌平
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
04/17
0
0
如何对NSMutableArray进行KVO

本文是我首发在iOS知识小集团队的,欢迎关注微博话题#ios知识小集#。我的微博:halohily 我们知道,iOS 中 KVO (key-value-observing) 的原理,简单来说就是重写了被观察属性的 set 方法。自...

halohily
05/22
0
0
[北京望京][15K-20K] 掘金招聘 iOS 开发

号外!号外!iOS 工程师又有人要啦! 望京 SOHO,望京 SOHO,iOS 工程师招聘了 你你你不来不来参加参加,你快投快投简历啊 不用犹豫了,我们等的就是你! ̋(ˊᵒ̴̶̷̤ ꇴ ᵒ̴̶̷̤ˋ)...

稀土君
07/11
0
0
如何判断你是合格的高级iOS开发工程师?

前言 随着移动互联网的高速发展泄洪而来,有意学习移动开发的人越来越多了,竞争也是越来越大,需要学习的东西很多。如何才能在激烈的移动开发者竞争中一枝独秀,成为一名真正合格的高级iOS...

_小迷糊
05/26
0
0
iOS商城demo、音乐播放器、视频通话、自定义搜索、转场动画等源码

iOS精选源码 微信自定义搜索框实现(http://www.code4app.com/thread-13182-1-1.html) 一个商城Demo,持续更新中(http://www.code4app.com/thread-13957-1-1.html) 在Object-C中学习数据结构与...

sunnyaigd
07/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

RabbitMQ在CentOS环境安装

1.废话不多说准备一台虚拟机,系统为centos,我这里使用的系统版本如下图所示:

凌晨一点
43分钟前
0
0
线程池相关

在java.util.concurrent包下,提供了一系列与线程池相关的类。 使用线程池的好处 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗; 提高响应速度。当任务到达时,任务...

edwardGe
45分钟前
0
0
学习大数据这三个关键技术是一定要掌握!

大数据时代全面来临,大数据、人工智能等技术引领科技创新潮流,获得国家政策大力支持,前景广阔。学习大数据技术的人自然是络绎不绝, 学习大数据虽然是一个趋势,但也要注意大数据培训课程...

董黎明
今天
0
0
jetbrains 上传代码到github

设置中找github 获取token 验证是否成功 测试git 生成key,一路回车即可 ssh-keygen -t rsa -C “youremail@example.com” 打开pub复制key,需要再次输入一次密码 验证是否成功,输入yes即可...

阿豪boy
今天
0
0
分布式服务框架(拾遗)

前言 现在的大部分工程都已经是基于分布式架构来处理。所以这里对分布式框架做一个简单的总结 常用的RPC框架 RPC框架原理 RPC(Remote Procedure Call,远程过程调用)一般用来实现部署在不同...

kukudeku
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部