iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)
先给答案,我们再探具体:
利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类
当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数
willChangeValueForKey:
父类原来的setter
didChangeValueForKey:
内部会触发监听器(Oberser)的监听方法( observeValueForKeyPath:ofObject:change:context:)
我们要手动触发kvo的话,就调用willChangeValueForKey: 和didChangeValueForKey: 方法
我们创建一个person对象,并含有age属性,赋值1,添加监听方法,在touchsbegin方法里面改变age的值,
实现监听方法,我们在添加kvo监听前,分别打印person1的类对象的值,如下
我们发现打印不同,添加监听后,新生成一个类NSKVONotifying_Peerson类对象,根据我们之前学的isa指针,实例对象的isa指针指向他的类对象,我们可以用下图表示,
在这个新生成的类对象里面实现的就是
- (void)setAge:(int)age
{_NSSetIntValueAndNotify();
}// 伪代码
void _NSSetIntValueAndNotify()
{[self willChangeValueForKey:@"age"];[super setAge:age];[self didChangeValueForKey:@"age"];
}- (void)didChangeValueForKey:(NSString *)key
{// 通知监听器,某某属性值发生了改变[oberser observeValueForKeyPath:key ofObject:self change:nil context:nil];
}
有人会问我们为什么知道是调用了_NSSetIntValueAndNotify()这个函数,接下来就来验证,
// [self.person1 methodForSelector:@selector(setAge:)] 这个为获得IMP
NSLog(@"person1添加KVO监听之前 - %p %p",[self.person1 methodForSelector:@selector(setAge:)],[self.person2 methodForSelector:@selector(setAge:)]);//打印为 person1添加KVO监听之前 - 0x10935f630 0x10935f630// 给person1对象添加KVO监听NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;[self.person1 addObserver:self forKeyPath:@"age" options:options context:@"123"];NSLog(@"person1添加KVO监听之后 - %p %p",[self.person1 methodForSelector:@selector(setAge:)],[self.person2 methodForSelector:@selector(setAge:)]);
// 打印为person1添加KVO监听之后 - 0x1096ba3d2 0x10935f630
在这里打断点,在lldb里面打印 p (IMP)0x1096ba3d2 这样就会打印对应的方法 :(IMP) $0 = 0x00000001096ba3d2 (Foundation`_NSSetIntValueAndNotify),从这里我们就看到了是调用_NSSetIntValueAndNotify函数。在这里在附上kvc赋值和取值的原理:
iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)相关推荐
- 终于明白那些年知其然而不知其所以然的iOS内存管理方式
终于明白那些年知其然而不知其所以然的iOS内存管理方式 前言 从我开始学习iOS的时候,身边的朋友.网上的博客都告诉我iOS的内存管理是依靠引用计数的,然后说引用计数大于1则对象保存在内存的堆中而引用 ...
- 微信公众号内下载pdf等文件,受微信所限制,安卓和IOS不同处理方式(最最最优版)
继上一篇文章微信公众号内下载pdf等文件,受微信所限制,安卓和IOS不同处理方式 后觉得还有更好的解决办法,这次真的找到更加优化版本,一定需要后台配合才行:后台接口返回Blob,后端设置respons ...
- iOS crash 定位方式
文章目录 iOS crash 定位方式 1. symbolicatecrash 定位 2. atos 定位 iOS crash 定位方式 1. symbolicatecrash 定位 在iOS 中系统 ...
- iOS In House方式发布
这两天In House签名的时候,提示SSL证书过期了.又折腾了一把iOS In House方式发布.这里开一篇文章记录一下过去折腾In House的经过,未来再修改也更新在这里. 最早在12年的时候 ...
- ios::app与ios::ate打开方式有什么不同??
看一个资料上说: 1.ios::app ----写入的数据将被追加在文件的末尾,此方式使用ios::out 2.ios::ate ----写入的数据将被追加在文件的末尾,此方式不使 ...
- iOS 数据持久化方式 - 归档 反归档
所谓归档:将复杂对象转化为NSData类型数据(复杂-->归档-->NSData--->WriteToFile) 注意:归档是将对象转化为数据字节,以文件的形式存储在磁盘上, 所谓反 ...
- 微信公众号内下载pdf等文件,受微信所限制,安卓和IOS不同处理方式
前言: IOS手机可以直接下载文件,但是需要后端设置Content-Disposition和Content-Type 安卓手机只能打开其他浏览器下载,(别问我怎么知道的,试出来的结果),所以跳转至中专 ...
- ios 4种方式防护label.text = @(100)崩溃
服务器在给客户端接口的时候一般是json,正常情况下约定是NSString类型,但是有时候服务器给到就是NSNumber类型.如果是需要展示的数据,label.text = @(100),这样就会崩溃 ...
- ios隐藏标题栏方式
info.plist View controller-based status bar appearance NO xcode 设置 Hide status bar 选中
最新文章
- python 靶心_手把手教你使用Python实战反欺诈模型|原理+代码
- 数据挖掘导论读书笔记7 Apriori算法
- WINDOWS 下编译ace
- Tensorflow:在Tensorflow的不同版本中如何实现Xavier参数权重初始化
- Android init第三、四部分详细分析
- 搜狗2011笔试题+答案解析
- 吴恩达深度学习2.3笔记_Improving Deep Neural Networks_超参数调试 和 Batch Norm
- python创建maven工程_Maven项目
- 45.Linux/Unix 系统编程手册(下) -- System V IPC 介绍
- Redhat6.8安装docker环境
- 职称计算机 frontpage 2003,计算机职称考试FrontPage2003考试大纲
- PYTHON通过高德API实现城市地址与经纬度批量转换(每十个一组查询)
- Linux编辑grldr文件,使用syslinux完美引导GRLDR。
- matlab生成三维分形,MATLAB生成分形树.ppt
- 【学习笔记】线段树详解(全)
- Web服务器技术的优缺点有哪些?
- 习题6 3.6.2 典型题例解析 3.6.3 自测训练
- 漏洞复现----11、GlassFish任意文件读取
- kerberos详解
- 文件传服务器上全是乱码,解决txt文件上传oss服务器乱码的问题