iOS面试题(十四)Runtime --消息传递机制(缓存查找)

4.动态运行时(RunTime)

  • 基础数据结构
  • 对象、类对象、元类对象是怎么理解的?以及他们之间的关系是怎样的(实例与类对象之间的关系以及类对象与元类对象之间的关系)?
  • OC语言中的消息传递机制是怎样的?
  • 缓存查找  (我们进行方法查找的过程当中,如何进行缓存的方法查找?会使用到系统或者说Runtime中一个方法缓存的机制,这个机制又是怎样运行的呢?)
  • 消息转发流程是怎样的?
  • Method-Swizzling(方法混写)是Runtime的一种运用(我们可以再运行时,去替换一些方法的实现,也得益于动态运行时这一个特性),可能会结合实际的场景,比如说通过时长统计框架这样的考察来了解对于Runtime的Methood-Swizzling技术的一个实际的运用
  • 动态添加方法(Runtime提供的功能实现)
  • 动态方法解析(Runtime提供的功能实现)
     

缓存查找流程


我们在缓存查找方法过程当中,实际的问题就是根据给定的方法选择器(SEL),来查找(bucket_t)中对应的方法实现(IMP)

bucket_t是方法选择器和方法实现的封装体,根据SEL去cache_t中找到bucket_t:

  • 首先根据给定的方法选择器(SEL),通过一个函数f(key)来映射出对应的bucket_t在数组中的位置
    这一步实际是哈希查找,哈希查找实际上是通过我们给定的值,
  • 经过哈希函数算法key&mask(选择器因子key和对应的一个mask做谓语操作),
    算出的值就是给定值在对应数组中的索引位置,提高了查找效率
  • 查找到选择器因子(SEL)对应的bucket_t之后,可以提取对应的IMP函数指针,返回给调用方

在当前类中的查找

  • 当前类中有对应的方法列表
  • 对于已排序好的方法列表,采用二分查找算法查找方法对应的执行函数实现
  • 对于没有排序的列表,采用一般遍历去查找方法对应的执行函数实现

ps:二分查找算法二分查找针对的是一个有序的数据集合,查找思想有点类似分治思想。每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。

父类逐级查找

  • 通过当前类结构(curClass)的superClass成员变量 去查找(访问)它的父类
     把当前类转移到父类之后,需要判断父类是否为nil(NSObject的superClass就是nil),为nil则结束
  • 若有父类,则在父类的缓存中查找对应的方法实现,
    根据当前方法的选择器因子,在缓存中查到了方法实现,就结束了父类逐级查找流程,
  • 若在父类缓存中没有查找到方法选择器所对应的方法实现,就需要遍历当前类的父类的方法列表,
    来看是否有对应的方法实现,若有则返回,
    若没有,继续遍历当前类的父类的父类,一直沿着superClass指针逐级向上查找,
    直到NSObject,取父类为nil时,就结束了查找流程

总结

  1. 缓存是否命中,缓存查找是哈希查找
  2. 当前类方法列表是否命中,已排序好的是二分查找,未排序好的是一般查找
  3. 逐级父类方法列表是否命中,根据superClass指针逐级查找父类,在父类中也是先查找缓存,再查找父类

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值