isa详解

本文深入解析了ARM64架构下Objective-C运行时的ISA优化策略,介绍了ISA从普通指针到共用体结构的转变,以及如何通过位域存储更多对象信息,如关联对象、C++析构函数、引用计数等,同时探讨了ISA在类对象、元类对象中的实际应用,以及其对方法缓存的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在arm64架构之前,isa就是一个普通的指针,存储着Class、Meta-Class对象的内存地址

从arm64架构开始,对isa进行了优化,变成了一个共用体(union)结构,还使用位域来存储更多的信息

nonpointer

0,代表普通的指针,存储着Class、Meta-Class对象的内存地址

1,代表优化过,使用位域存储更多的信息

has_assoc

是否有设置过关联对象,如果没有,释放时会更快

has_cxx_dtor

是否有C++的析构函数(.cxx_destruct),如果没有,释放时会更快

shiftcls

存储着Class、Meta-Class对象的内存地址信息

magic

用于在调试时分辨对象是否未完成初始化

weakly_referenced

是否有被弱引用指向过,如果没有,释放时会更快

deallocating

对象是否正在释放

extra_rc

里面存储的值是引用计数器减1

has_sidetable_rc

引用计数器是否过大无法存储在isa中 如果为1,那么引用计数会存储在一个叫SideTable的类的属性中

所以我们在源码中看到类对象,元类对象的实际地址值都要用isa地址& ISA_MASK 一个值,这就是位运算来获得实际shiftcls值。

#   define ISA_MASK        0x00007ffffffffff8ULL

由isa我们重新来看class结构

class_rw_t

由class_data_bits_t & MASK值获得class_rw_t,

class_rw_t里面的methods、properties、protocols是二维数组,是可读可写的,包含了类的初始内容、分类的内容

class_ro_t

class_ro_t里面的baseMethodList、baseProtocols、ivars、baseProperties是一维数组,是只读的,包含了类的初始内容

method_t

method_t是对方法\函数的封装

SEL代表方法\函数名,一般叫做选择器,底层结构跟char *类似

  1. 可以通过@selector()和sel_registerName()获得
  2. 可以通过sel_getName()和NSStringFromSelector()转成字符串
  3. 不同类中相同名字的方法,所对应的方法选择器是相同的

types包含了函数返回值、参数编码的字符串

一般我们正常写的函数都默认包含了两个参数(self,SEL),我们写申明一个test方法,

- (void)test;


- (void)test{
}

打印出来types就变成 v16@0:8,v代表返回值,16为总的字节,@代表self,0表示从第0哥开始,:代表SEL

cache

Class内部结构中有个方法缓存(cache_t),用散列表(哈希表)来缓存曾经调用过的方法,可以提高方法的查找速度

缓存原理为地址值& _mask 为索引,SEL作为key,用空间换时间,当这个索引存在时,就会到索引减1那,还有值时,继续减1,为0时 则扩充_mask 并清空之前的数据,因为&_mask 得到的值肯定会小于等于_mask,这样就不会越界。

bucket_t * cache_t::find(SEL s, id receiver)
{
    assert(s != 0);

    bucket_t *b = buckets();
    mask_t m = mask();
    mask_t begin = cache_hash(s, m);
    mask_t i = begin;
    do {
        if (b[i].sel() == 0  ||  b[i].sel() == s) {
            return &b[i];
        }
    } while ((i = cache_next(i, m)) != begin);

    // hack
    Class cls = (Class)((uintptr_t)this - offsetof(objc_class, cache));
    cache_t::bad_cache(receiver, (SEL)s, cls);
}


static inline mask_t cache_hash(SEL sel, mask_t mask) 
{
    return (mask_t)(uintptr_t)sel & mask;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值