美文网首页
读objc_msgSend实现发现一个有趣的点

读objc_msgSend实现发现一个有趣的点

作者: 陈_振 | 来源:发表于2018-12-20 21:49 被阅读0次

    众所周知,每次从类的缓存列表中查找对应实现时,'objc_msgSend'源码中会将'SEL'与'cache.mask'进行与运算。
    而有趣的地方在于每个Class类对象初始化时会为缓存分配4个'bucket',当缓存数量达到总容量的3/4时,系统会将'bucket'的数量增大'2'倍。因此'bucket'的数量始终是2的n次幂。转为2进制所有有效位均为1。基于此,才可以将'SEL'与'cache.mask'进行与运算,如果'bucket'的数量没有这个特性的话,则不能进行与运算,只能通过取余的方式(原因下面会解释),这样的话效率就会差很多。

    解释:

    如果'bucket'的数量不为2的n次幂,如,0x10(表示最大下标为2),此时用0和1分别与0x10进行与运算得到的结果均为0。此时只能进行取余操作才能满足要求。如果'bucket'的数量为2的n次幂,如,0x11(表示最大下标为3)则任何不同的数(转换为二进制后位数与0x11的位数一直)与0x11进行与运算都不会重复,且最大值不会超过0x11,因此可以通过与运算的方式取索引。

    总结:

    使用与运算比取余操作求数组下标效率要高,前提是mask的值必须为2的n次幂。

    参考文章:
    objc_msgSend
    Memory barrier

    相关文章

      网友评论

          本文标题:读objc_msgSend实现发现一个有趣的点

          本文链接:https://www.haomeiwen.com/subject/bfgukqtx.html