美文网首页iOS Developer
Objective-C 小记(2)对象 2.0

Objective-C 小记(2)对象 2.0

作者: KylinRoc | 来源:发表于2017-01-27 00:19 被阅读99次

    在 Objective-C 运行时现在的实现中,objc_objcet 的结构体是这样定义的

    struct objc_object {
    private:
        isa_t isa;
    };
    

    isaClass 变成了 isa_t,那这个 isa_t 是个什么东西呢?它的定义在 x86-64 上是这样的

    union isa_t
    {
        Class cls;
        uintptr_t bits;
        
        struct {
            uintptr_t nonpointer        : 1;
            uintptr_t has_assoc         : 1;
            uintptr_t has_cxx_dtor      : 1;
            uintptr_t shiftcls          : 44; // MACH_VM_MAX_ADDRESS 0x7fffffe00000
            uintptr_t magic             : 6;
            uintptr_t weakly_referenced : 1;
            uintptr_t deallocating      : 1;
            uintptr_t has_sidetable_rc  : 1;
            uintptr_t extra_rc          : 8;
        };
    };
    

    uintptr_t 是一个和指针一样长的无符号整形,方便对指针进行算术运算。

    知道联合的都清楚,clsbits 和最后的匿名结构体是占用同一片内存的。这是 Objective-C 运行时对 64 位的优化,我们知道指针的长度是和 CPU 有关系,在 64 位下它就有 64 位长,如果和之前一样,整个指针都用来存一个地址,是比较浪费的,甚至虚拟内存根本都没那么大。所以可以让指针中一部分位拿来做别的用途,即所谓的 Tagged Pointer

    可以参考这篇文章知道这些位的用途:

    • 1 bit nonpointer 用来标示是否「不是单纯的指针」
    • 1 bit has_assoc 用来标示是否有关联对象
    • 1 bit has_cxx_dtor 用来标示是否有 C++ destructor
    • 44 bit shiftcls 右移(shift)了 3 位(8 byte 对齐,最后 3 位总是 0)的 Class(cls)地址
    • 6 bit magic 给 debugger 区分对象和垃圾内存的值
    • 1 bit weakly_referenced 是否被弱引用过
    • 1 bit deallocating 是否正在销毁
    • 1 bit has_sidetable_rc 是否有在别的地方存引用计数(引用计数太大,extra_rc 存不下了)
    • 8 bit extra_rc 引用计数超过 1 的部分(如果这里是 5,那对象的引用计数就是 6)

    总结

    这些位都是给一些不同功能的优化。像对消息发送来说,只要能获取到 Class,它对这个实际结构是不关心的。所以之前消息发送的文章中,不知道这个结构对理解原理也是没有什么关系的,只是在实现细节部分会有所不同。这些不同位的使用细节,也是要通过之后不同具体功能的文章来具体分析了。

    相关文章

      网友评论

        本文标题:Objective-C 小记(2)对象 2.0

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