前言本质

Automatic key-value observing is implemented using a technique called isa-swizzling

这计划的意思就是
自动的键值观察的实现基于 isa-swizzling

原理

1.KVO是基于runtime机制实现的

2.当某个类的属性对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,

在这个派生类中重写基类中任何被观察属性的setter 方法。

派生类在被重写的setter方法内实现真正的通知机制

3.如果原类为Dog,那么生成的派生类名为NSKVONotifying_Dog

4.每个类对象中都有一个isa指针指向当前类,当一个类对象的第一次被观察,那么系统会偷偷将isa指针指向动态生成的派生类,从而在给被监控属性赋值时执行的是派生类的setter方法

5.键值观察通知依赖于NSObject 的两个方法: willChangeValueForKey: 和 didChangevlueForKey:;在一个被观察属性发生改变之前, willChangeValueForKey:一定会被调用,这就 会记录旧的值。而当改变发生后,didChangeValueForKey:会被调用,继而 observeValueForKey:ofObject:change:context: 也会被调用。

一  KVO 的使用


#import "ViewController.h"
#import "Person.h"
@interface ViewController ()@property (nonatomic,strong)Person *p1;@property (nonatomic,strong)Person *p2;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view.// 监听person 类的属性值self.p1 = [[Person alloc]init];self.p1.name = @"p1_dog";self.p2 = [[Person alloc]init];self.p2.name = @"p2_dog";NSKeyValueObservingOptions val = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;[self.p1 addObserver:self forKeyPath:@"name" options:val context:nil];
}- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{self.p1.name = @"p1_cate";self.p2.name = @"p2_cate";}- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{NSLog(@"%@ value changed from %@",keyPath,change);
}@end

二 如何实现监听 ?

本质原因就是这两个对象的isa 指向不一样吗,主要是使用runtime 动态生成了一个派生类

1 如果未使用kvo 监听对象的时候

使用KVO 监听的话

三 代码验证


利用runtime 进行验证一下子,进入断电模式打印一下

 self.p1 = [[Person alloc]init];self.p1.name = @"p1_dog";self.p2 = [[Person alloc]init];self.p2.name = @"p2_dog";// 打印添加监听之前 setName的方法NSLog(@"监听之前%p--%p",[self.p1 methodForSelector:@selector(setName:)],[self.p1 methodForSelector:@selector(setName:)]);NSKeyValueObservingOptions val = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;[self.p1 addObserver:self forKeyPath:@"name" options:val context:nil];NSLog(@"监听之后%p--%p",[self.p1 methodForSelector:@selector(setName:)],[self.p1 methodForSelector:@selector(setName:)]);NSLog(@"end");

添加之后,setName 的实现走的是_NSSetObjectValueAndNotify 方法

四 KVO的 调用顺序

KVO 的调用顺序是:

  • 调用 willChangeValueForKey:
  • 调用原来的 setter 实现
  • 调用 didChangeValueForKey:

也就是说 didChangeValueForKey: 内部必然是调用了 observerobserveValueForKeyPath:ofObject:change:context:方法。

8 iOS中KVO 的本质相关推荐

  1. iOS中KVO模式的解析与应用

    最近老翁在项目中多处用到了KVO,深感这种模式的好处.现总结如下: 一.概述 KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单 ...

  2. iOS中你可能没有完全弄清楚的(二)自己实现一个KVO源码及解析

    前几天写了一篇blog(点这里),分析了系统KVO可能的实现方式.并添加了简单代码验证. 既然系统KVO不好用,我们完全可以根据之前的思路,再造一个可以在项目中使用的KVO的轮子. 代码已经上传到gi ...

  3. iOS 中KVC、KVO、NSNotification、delegate 总结及区别

    iOS 中KVC.KVO.NSNotification.delegate 总结及区别 1.KVC,即是指 NSKeyValueCoding,一个非正式的Protocol,提供一种机制来间接访问对象的属 ...

  4. iOS下KVO使用过程中的陷阱

    KVO,全称为Key-Value Observing,是iOS中的一种设计模式,用于检测对象的某些属性的实时变化情况并作出响应.网上广为流传普及的一个例子是利用KVO检测股票价格的变动,例如这里.这个 ...

  5. ios kvo 要引入_iOS中KVO的使用

    KVO,全称为Key-Value Observing,是iOS中的一种设计模式,用于检测对象的某些属性的实时变化情况并作出响应.网上广为流传普及的一个例子是利用KVO检测股票价格的变动,例如这里.这个 ...

  6. [iOS开发]iOS中的Hash

    文章目录 前言 关联对象的底层原理 weak的实现原理 KVO的实现原理 iOS App签名的原理 对象引用计数存储的位置 Runloop与线程的存储关系 NSDictionary的原理 哈希表 哈希 ...

  7. iOS 中的单元测试

    作者:bool周  原文链接:iOS 中的单元测试 最近团队内部为了保证代码质量,要求单元测试覆盖率 80%+.在编写单元测试过程中,等到了一些收获,为此总结一下. 概述 Unit test 是保证代 ...

  8. iOS底层-KVO分析与自定义

    KVO分析与自定义 背景 准备 KVO一些细节 KVO探索分析 KVO 底层原理 小结: KVO自定义 自定义KVO要知道: 1,KVO是对setter方法进行观察,过滤实例方法 2,添加KVO(核心 ...

  9. iOS中的HotFix方案总结详解

    iOS中的HotFix方案总结详解 相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结.iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dy ...

最新文章

  1. 机器学习数据预处理之缺失值:后向填充
  2. flyway常用配置_Spring Boot 2 实战:使用 Flyway 管理你数据库的版本变更
  3. Longest Palindromic Substring
  4. 深入理解及配置ISA Server 2006访问规则
  5. 提高学生对计算机学科学习兴趣的研究的结题报告,《如何在体育教学中运用体育游戏》的研究结题报告...
  6. 双击计算机桌面误删,手提电脑双击界面自动删除是哪里问题
  7. 什么是干货,什么是鸡汤?
  8. 实现类似shared_ptr的引用计数
  9. 基于Matlab App Designer的语音信号分析与处理(一):语音信号的采集,时域、频域分析
  10. PDF识别文字、关键字,获取对应坐标,用于插入电子签名
  11. 高性能mysql_高性能MySQL
  12. 探讨6410的启动过程
  13. Angular—生命周期函数
  14. CloudCompare学习记录(一)主要概念
  15. 宏的录制以及在Visual Basic中显示代码
  16. g729源码分析-5-基音周期搜索(下)
  17. 基于PHP的旅游网站的开发与设计
  18. 税率taxjar对接
  19. VS2003版本Json格式文件的解析
  20. 计算服务器Centos 7.9 配置torque 6.1.2 单服务器

热门文章

  1. vs2008/2010安装无法打开数据文件解决方案
  2. C#学习笔记8:HTML和CSS基础学习笔记
  3. Javascript中二进制数据处理方法
  4. linux下查看内存使用情况
  5. 微软极品Sysinternals Suite工具包使用指南
  6. CentOS的Gearman安装与使用无错版
  7. 锦上添花DataGrid!
  8. asp.net 2.0中用GRIDVIEW插入新记录
  9. Spring源码分析【2】-Tomcat和Sping的连接点
  10. 设计模式之迭代器模式(Iterator)摘录