iOS 底层探索篇 —— KVO 底层原理(下)

1. 自定义KVO

创建一个NSObject分类,并添加三个方法,lg_addObserver,lg_observeValueForKeyPath和lg_removeObserver。
在这里插入图片描述

1.1 lg_addObserver

接下来就是方法的实现。那么对于lg_addObserver,实现的步骤大致如下:

  1. 验证是否存在setter方法 : 不让成员变量进来
  2. 动态生成子类
  3. isa的指向 : LGKVONotifying_LGPerson
  4. 保存观察者信息,setter方法会使用到这些信息

实现代码如下:
总体流程:
在这里插入图片描述

  1. 验证是否存在setter方法 : 不让成员变量进来
    在这里插入图片描述
  2. 动态生成子类
    动态生成子类分以下几个步骤
  1. 防止重复创建生成新类
  2. 申请类
  3. 添加class方法
  4. 添加setter
  5. 注册类

实现如下:
在这里插入图片描述

这里需要展示父类也不是动态子类,所以重写class方法,返回动态子类的父类。
在这里插入图片描述
这里的是获取setter方法的名称的实现,也就是将getter的第一个字母变为大写,然后在前面插入set。
在这里插入图片描述
setter则是需要调用父类的setter设置新值,然后取出观察者,根据设置的option来对change进行处理,然后发送通知,也就是调用lg_observeValueForKeyPath方法。
在这里插入图片描述
注意这里的observer要是weak属性,否则会有循环引用的问题。
在这里插入图片描述

1.2 lg_removeObserver

lg_removeObserver实现的步骤大致如下:

  1. 将储存的关于observer的信息移除
  2. 将isa重新指回原来的类

实现代码如下:
在这里插入图片描述

2. 自定义函数式KVO

lg_addObserver 和 lg_observeValueForKeyPath的话,那么就将逻辑代码和业务代码分开了,能不能用函数式编程思想,将他们放在一起呢?
实现一下。
先为KVO分类添加一个block,并且在addObserver的函数里面添加上这个block。
在这里插入图片描述
在保存信息的时候,将block也保存起来。
在这里插入图片描述

然后将原来的调用observeValueForket的地方改为调用block。
在这里插入图片描述

然后,外界的调用就变成了这样。
在这里插入图片描述

3. KVO自动销毁机制

KVO每次都需要手动去调用lg_removeObserver释放,那么能不能做到自动释放呢?
实现一下。
尝试在LGKVO分类里面重写dealloc方法,但是如果这样做的话,就会把所有的东西进行覆盖。
之前学过方法交换,那么是否可以在load的时候,把dealloc拦截下来,然后来到自己的实现里面。但是这样的话,那么所有的dealloc方法都会进行交换,明显不合理。
那么如果在进入KVO的时候进行交换,那么就会有交换多次的问题,还会对原始的dealloc方法有影响。

这里为实现KVO的动态子类里面添加dealloc方法,这样就相当于重写了,然后在实现里面将isa重新指回就可以了。
在这里插入图片描述
在这里插入图片描述
但是这样做还是不合理的,如果父类的实现里有太多的逻辑的话,那么应该怎么办呢?

4. FBKVOController

FBKVOController是Facebook开源的一个基于系统KVO实现的框架,其使用了函数式编程,可以一行代码实现系统KVO的三个步骤,可以同时对一个对象的多个属性进行监听,线程安全并且可以自动移除观察者。FBKVOController使用了中介者模式,通过创建一个FBKVOController的实例,并将所有监听、回调和释放的工作交过这个实例去完成。

那么FBKVOController是怎么实现自动remove的呢?
在VC中,FBKVOController的实例是VC的一个属性,当VC释放的时候,那么实例作为属性也会进行dealloc。
所以FBKVOController在dealloc里面调用了unobserveAll来进行观察者的释放。
在这里插入图片描述
实际调用_unobserveAll。
在这里插入图片描述
用_FBKVOSharedController单例调用unobserve来移除所有的观察者。
在这里插入图片描述
移除info后再调用removeObserver移除观察者。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值