isa结构分析

2020-09-10  本文已影响0人  为了自由的白菜

在对象调用alloc, 之后调用的最后一个方法是obj->initInstanceIsa, 它的作用是将isa指针与我们的对象关联起来, 我们来分析一下isa指针.

我们这里先看下isa指针初始化的源码:

inline void   
objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor)   
{   
    ASSERT(!isTaggedPointer());   
    
    if (!nonpointer) {  
        isa = isa_t((uintptr_t)cls);  
    } else {  
        ASSERT(!DisableNonpointerIsa);  
        ASSERT(!cls->instancesRequireRawIsa());  

        isa_t newisa(0);  
#if SUPPORT_INDEXED_ISA  
        ASSERT(cls->classArrayIndex() > 0);  
        newisa.bits = ISA_INDEX_MAGIC_VALUE;  
        // isa.magic is part of ISA_MAGIC_VALUE  
        // isa.nonpointer is part of ISA_MAGIC_VALUE  
        newisa.has_cxx_dtor = hasCxxDtor;  
        newisa.indexcls = (uintptr_t)cls->classArrayIndex();  
#else  
        newisa.bits = ISA_MAGIC_VALUE;  
        // isa.magic is part of ISA_MAGIC_VALUE  
        // isa.nonpointer is part of ISA_MAGIC_VALUE  
        newisa.has_cxx_dtor = hasCxxDtor;  
        newisa.shiftcls = (uintptr_t)cls >> 3;  
#endif  
        // This write must be performed in a single store in some cases  
        // (for example when realizing a class because other threads  
        // may simultaneously try to use the class).  
        // fixme use atomics here to guarantee single-store and to  
        // guarantee memory order w.r.t. the class index table  
        // ...but not too atomic because we don't want to hurt instantiation  
        isa = newisa;  
    }
}

其中通过宏ISA_INDEX_MAGIC_VALUE 我们可以找到isa的宏定义(此处只写出了x86_64)(还有arm64, armv7k or arm64_32)如下:

# elif __x86_64__  
#   define ISA_MASK        0x00007ffffffffff8ULL  
#   define ISA_MAGIC_MASK  0x001f800000000001ULL  
#   define ISA_MAGIC_VALUE 0x001d800000000001ULL  
#   define ISA_BITFIELD                                                        \  
      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  
#   define RC_ONE   (1ULL<<56)  
#   define RC_HALF  (1ULL<<7)  

我们都知道isa所占的内存大小为8字节, 一字节8位, 总共64位, 那么上面的代码的意思就是该isa指针所对应内存的顺序以及所占内存的大小. (本文在此并不做证明, 只是学习记录笔记)

记录一些编译指令

clang -rewrite-objc main.m -o main.cpp
clang -rewrite-objc -fobjc-arc -fobjc-runtime=ios-13.0.0 -isysroot / Applications/Xcode.app/Contents/Developer/Platforms/ iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator13.0.sdk main.m 
xcrun -sdk iphonesimulator clang -arch arm64 -rewrite-objc main.m -o main-arm64.cpp //模拟器
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main- arm64.cpp //手机
上一篇 下一篇

猜你喜欢

热点阅读