先给答案,我们再探具体:

利用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的本质是什么?)相关推荐

  1. 终于明白那些年知其然而不知其所以然的iOS内存管理方式

    终于明白那些年知其然而不知其所以然的iOS内存管理方式 前言 从我开始学习iOS的时候,身边的朋友.网上的博客都告诉我iOS的内存管理是依靠引用计数的,然后说引用计数大于1则对象保存在内存的堆中而引用 ...

  2. 微信公众号内下载pdf等文件,受微信所限制,安卓和IOS不同处理方式(最最最优版)

    继上一篇文章微信公众号内下载pdf等文件,受微信所限制,安卓和IOS不同处理方式 后觉得还有更好的解决办法,这次真的找到更加优化版本,一定需要后台配合才行:后台接口返回Blob,后端设置respons ...

  3. iOS crash 定位方式

    文章目录 iOS crash 定位方式 1. symbolicatecrash 定位 2. atos 定位 iOS crash 定位方式 1. symbolicatecrash 定位 在iOS 中系统 ...

  4. iOS In House方式发布

    这两天In House签名的时候,提示SSL证书过期了.又折腾了一把iOS In House方式发布.这里开一篇文章记录一下过去折腾In House的经过,未来再修改也更新在这里. 最早在12年的时候 ...

  5. ios::app与ios::ate打开方式有什么不同??

    看一个资料上说:   1.ios::app    ----写入的数据将被追加在文件的末尾,此方式使用ios::out   2.ios::ate    ----写入的数据将被追加在文件的末尾,此方式不使 ...

  6. iOS 数据持久化方式 - 归档 反归档

    所谓归档:将复杂对象转化为NSData类型数据(复杂-->归档-->NSData--->WriteToFile) 注意:归档是将对象转化为数据字节,以文件的形式存储在磁盘上, 所谓反 ...

  7. 微信公众号内下载pdf等文件,受微信所限制,安卓和IOS不同处理方式

    前言: IOS手机可以直接下载文件,但是需要后端设置Content-Disposition和Content-Type 安卓手机只能打开其他浏览器下载,(别问我怎么知道的,试出来的结果),所以跳转至中专 ...

  8. ios 4种方式防护label.text = @(100)崩溃

    服务器在给客户端接口的时候一般是json,正常情况下约定是NSString类型,但是有时候服务器给到就是NSNumber类型.如果是需要展示的数据,label.text = @(100),这样就会崩溃 ...

  9. ios隐藏标题栏方式

    info.plist View controller-based status bar appearance NO xcode 设置 Hide status bar 选中

最新文章

  1. python 靶心_手把手教你使用Python实战反欺诈模型|原理+代码
  2. 数据挖掘导论读书笔记7 Apriori算法
  3. WINDOWS 下编译ace
  4. Tensorflow:在Tensorflow的不同版本中如何实现Xavier参数权重初始化
  5. Android init第三、四部分详细分析
  6. 搜狗2011笔试题+答案解析
  7. 吴恩达深度学习2.3笔记_Improving Deep Neural Networks_超参数调试 和 Batch Norm
  8. python创建maven工程_Maven项目
  9. 45.Linux/Unix 系统编程手册(下) -- System V IPC 介绍
  10. Redhat6.8安装docker环境
  11. 职称计算机 frontpage 2003,计算机职称考试FrontPage2003考试大纲
  12. PYTHON通过高德API实现城市地址与经纬度批量转换(每十个一组查询)
  13. Linux编辑grldr文件,使用syslinux完美引导GRLDR。
  14. matlab生成三维分形,MATLAB生成分形树.ppt
  15. 【学习笔记】线段树详解(全)
  16. Web服务器技术的优缺点有哪些?
  17. 习题6 3.6.2 典型题例解析 3.6.3 自测训练
  18. 漏洞复现----11、GlassFish任意文件读取
  19. kerberos详解
  20. 文件传服务器上全是乱码,解决txt文件上传oss服务器乱码的问题

热门文章

  1. JDBC——jdbcUtils加载配置文件赋值
  2. 机器视觉学习笔记(4)——单目摄像机标定参数说明
  3. Python【Python基础】
  4. 【推荐】iOS汉字转拼音第三方库
  5. adb命令开启手机的一些功能,请问怎么操作?
  6. Ruby用SciTE输出中文报错问题解决
  7. vs2010无法调试JS
  8. Windows客户机脱域问题及解决办法
  9. Windows服务异常自动关闭
  10. 安装tomcat出现failed to install tomcat8 service错误及解决方法