2020年对iOS和Mac中OC runtime的三项改进

前言

文章内容来自于WWDC 2020Advancements in the Objective-C runtime,主要介绍了2020年对iOS和Mac中OC runtime的三项改进。建议直接观看原视频。

  • 类数据结构class_rw_ext_t
  • iOS14后相对方法列表的变化,从64位绝对地址变为32位相对偏移
  • tagged pointer以及iOS14后ARM上tagged pointer结构的变化。

一、类数据结构的变化

Objective-C运行时用于跟踪类的数据结构发生了变化。
在这里插入图片描述
当类第一次从磁盘加载到内存时,它们像上图这样开始,但是一旦使用它们便会更改。Swift类和Objective-C类共享此基础结构,因此每个Swift类也具有这些数据结构
要了解随后发生的情况,了解干净内存和脏内存之间的区别很有用。

  • clear memory是指加载后不会发生更改的内存。
  • dirty memory是指在进程动行时会发生更改的内存。

类结构一经使用就会变为dirty memory,因为动行时会向它写入新的数据。dirty memory比clear memory要昂贵得多,只要进程在运行,它就必须一直存在;另一方面,clear memory可以进行移除从而节省更多的运行空间,因为如果你需要clear memory系统可以从磁盘中重新加载。macOS可以选择换出dirty memory,但是因为iOS不使用Swap,所以dirty memory在iOS中代价很大。dirty memory是类数据分为两部分的原因。
在这里插入图片描述运行时需要追踪每个类的更多的信息,所以当一个类首次被使用,运行时会为它分配额外的存储容量,也就是class_rw_t,用于读取-编写数据。在class_rw_t中存储了只有运行时才会生成的新信息,例如,所有的类都会链接成一个树状结构,通过First Subclass和Next Sibling Class指针实现,这允许运行时遍历当前使用的所有类,这对于使方法缓存无效非常有用。
那么,为什么当Mehods、Properties、Protocols在class_ro_t中已经存在,还要在class_rw_t中设计呢?因为它们可以在运行时进行更改,当category被加载时它可以向类中添加新的方法,而且程序员可以通过使用运行时API动态地添加它们。因为class_ro_t是只读的,所以我们需要在class_rw_t中追踪这些东西。现在这样做会占用相当多的内存,在任何给定的设备中都有很多类在使用,但是通过检查实际设备上的使用情况,发现大约只有10%的类真正的更改了它们的方法,而且只有Swift类会使用Demangled Name字段并且Swift类并不需要这个字段,除非访问它们的Object-C名称时才需要,所以我们可以拆掉那些平时不用的部分,这将class_rw_t的大小减少了一半,对于那些确实需要这些额外信息的类,我们可以分配这些扩展记录中的一个,并把它滑到类中供其使用。
在这里插入图片描述
在这里插入图片描述
通过heap Xcode | egrep 'class_rw|COUNT'我们可以看一下class_rw_t和class_rw_ext_t在Xcode中的占用如下
在这里插入图片描述
从上面COUNT可以看出有15604个使用了class_rw_t结构,但是只有2479个大约13.7%使用的是class_rw_ext_t扩展结构,BYTES中表示的是我们必须分配给扩展类型的内存量,所以很容易计算出通过这个改变所节省的内存。对于dirty memory而主这是真正的节省内存。
现在很多从类中获取数据的代码必须同时处理这些有扩展数据和没有扩展数据的类,运行时会处理这一切,并且从外部看一切都像往常一样工作,只是使用更少的内存,之所以会这样,是因为记取这些结构的代码都在运行时内并且还会同时进行更新,坚持使用这些API真的很重要,因为任何试图直接访问这些数据结构的代码,都将在今年(2020)的OS版本中停止工作,因为东西已经发生了变化,而且该代码不知道新的布局,这将会引起崩溃

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值