runtimeruntimeiOS开发知识

RunTime源码中的基本结构体【类,对象,isa】

2019-07-17  本文已影响0人  太阳骑士索拉尔

关于我的仓库

前言

准备工作

类与对象

对象

objc_object

补充知识:OC类的本质

找到它?

#if !OBJC_TYPES_DEFINED
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;
#endif
struct objc_object {
    // isa结构体
private:
    isa_t isa;     //这里讲到了isa的类型是isa_t

public:
  //省略方法
};

isa_t

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};

objc_class

struct objc_class : objc_object {
    Class superclass;
    cache_t cache;            
    class_data_bits_t bits;  
    //省略方法
};
objc-isa-class-pointer

说明:isa指针

引入概念:元类与根类

isa闭环

isa闭环指针图

补充知识:类方法与实例方法的存储

isa详解

完整定义

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls;
    uintptr_t bits;
#if defined(ISA_BITFIELD)
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
#endif
};

uintptr_t bits【unsigned long bits】

union isa_t

结构分析

struct {
        ISA_BITFIELD;  // defined in isa.h
    };
    

//ISA_BITFIELD内容以及注解
# 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;   // 这个字段存储类是否有c++析构器
      uintptr_t shiftcls          : 44;    //存储cls类地址 /*MACH_VM_MAX_ADDRESS 0x7fffffe00000*/ 
      uintptr_t magic             : 6;           //校验          
      uintptr_t weakly_referenced : 1;          // 对象是否曾经或正在被弱引用,如果没有,可以快速释放内存           
      uintptr_t deallocating      : 1;         // 对象是否正在释放内存            
      uintptr_t has_sidetable_rc  : 1;             // 是否需要散列表存储引用计数。当extra_rc存储不下时,该值为1        
      uintptr_t extra_rc          : 8       // 引用计数数量,实际的引用计数减一
#   define RC_ONE   (1ULL<<56)
#   define RC_HALF  (1ULL<<7)

补充知识:arm 64与x86_64

各个部分存储空间

123俄 5566

isa_t的初始化

initIsa

inline void 
objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor) 
{
    assert(!isTaggedPointer()); 
    if (!nonpointer) {
        isa.cls = 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;
        newisa.has_cxx_dtor = hasCxxDtor;
        newisa.indexcls = (uintptr_t)cls->classArrayIndex();
#else
        newisa.bits = ISA_MAGIC_VALUE;  //0x001d800000000001ULL
        newisa.has_cxx_dtor = hasCxxDtor;
        newisa.shiftcls = (uintptr_t)cls >> 3;
#endif
        isa = newisa;
    }
}

补充知识:assert()函数

三个参数【Class cls】【bool nonpointer】【bool hasCxxDtor】

inline void 
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)
{
    assert(!cls->instancesRequireRawIsa());
    assert(hasCxxDtor == cls->hasCxxDtor());

    initIsa(cls, true, hasCxxDtor);
}
inline void 
objc_object::initIsa(Class cls, bool nonpointer, bool hasCxxDtor) 
{
    assert(!isTaggedPointer()); 
    if (!nonpointer) {
        isa.cls = cls;
    } else {
                //省略代码
    }
}

补充知识:ULL

真正初始化

isa_t newisa(0);
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;
isa = newisa;
000 小心心

isa诸多用处

获取cls地址:ISA() 方法

#define ISA_MASK 0x00007ffffffffff8ULL
inline Class 
objc_object::ISA() 
{
    return (Class)(isa.bits & ISA_MASK);
}

class方法

+ (Class)class {
    return self;
}

- (Class)class {
    return object_getClass(self);
}

Class object_getClass(id obj)
{
    if (obj) return obj->getIsa();
    else return Nil;
}

isMemberOfClass&&isKindOfClass

+ (BOOL)isMemberOfClass:(Class)cls {
    return object_getClass((id)self) == cls;
}

- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

- (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

objc_class扩充:bits

struct objc_class : objc_object {
    Class superclass;
    cache_t cache;            
    class_data_bits_t bits;  
    //省略方法
};

class_rw_t与class_ro_t

 class_rw_t *data() {
        return bits.data();
    }
    
//data()
 class_rw_t* data() {
        return (class_rw_t *)(bits & FAST_DATA_MASK);
    }

// class_rw_t定义
struct class_rw_t {
    // Be warned that Symbolication knows the layout of this structure.
    uint32_t flags;
    uint32_t version;

    const class_ro_t *ro;
    
    // 方法信息
    method_array_t methods;
    // 属性信息
    property_array_t properties;
    // 协议信息
    protocol_array_t protocols;

    Class firstSubclass;
    Class nextSiblingClass;

    char *demangledName;
  //省略方法
};
让我
struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;

    const uint8_t * ivarLayout;
    
    const char * name;
    // 方法列表
    method_list_t * baseMethodList;
    // 协议列表
    protocol_list_t * baseProtocols;
    // 变量列表
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    // 属性列表
    property_list_t *baseProperties;

    method_list_t *baseMethods() const {
        return baseMethodList;
    }
};

realizeClass方法

//精取代码
static Class realizeClass(Class cls)
{
    const class_ro_t *ro;
    class_rw_t *rw;
    Class supercls;
    Class metacls;
    bool isMeta;
    ro = (const class_ro_t *)cls->data(); //编译期间,cls->data指向的是class_ro_t结构体。cls->data()存放的是即ro中存储的是编译时就已经决定的原数据
    rw = (class_rw_t *)calloc(sizeof(class_rw_t), 1);   //初始化rw
    rw->ro = ro;    //rw中的ro赋值
    rw->flags = RW_REALIZED|RW_REALIZING;
    cls->setData(rw);
    rw->version = isMeta ? 7 : 0; 
    cls->chooseClassArrayIndex();
    methodizeClass(cls);    //运行期间,将ro中的内容赋值给rw
    return cls;
}

补充知识:addRootClass和addSubclass

static void addSubclass(Class supercls, Class subcls)
{
    runtimeLock.assertLocked();
    if (supercls  &&  subcls) {
        assert(supercls->isRealized());
        assert(subcls->isRealized());
        subcls->data()->nextSiblingClass = supercls->data()->firstSubclass;
        supercls->data()->firstSubclass = subcls;

        if (supercls->hasCxxCtor()) {
            subcls->setHasCxxCtor();
        }

        if (supercls->hasCxxDtor()) {
            subcls->setHasCxxDtor();
        }

        if (supercls->hasCustomRR()) {
            subcls->setHasCustomRR(true);
        }

        if (supercls->hasCustomAWZ()) {
            subcls->setHasCustomAWZ(true);
        }

        // Special case: instancesRequireRawIsa does not propagate 
        // from root class to root metaclass
        if (supercls->instancesRequireRawIsa()  &&  supercls->superclass) {
            subcls->setInstancesRequireRawIsa(true);
        }
    }
}

static void addRootClass(Class cls)
{
    runtimeLock.assertLocked();

    assert(cls->isRealized());
    cls->data()->nextSiblingClass = _firstRealizedClass;
    _firstRealizedClass = cls;
}

methodizeClass方法

//精取代码
// 设置类的方法列表、协议列表、属性列表,包括category的方法
static void methodizeClass(Class cls)
{
    runtimeLock.assertLocked();

    bool isMeta = cls->isMetaClass();
    auto rw = cls->data();
    auto ro = rw->ro;
    method_list_t *list = ro->baseMethods();
    if (list) {
        prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls));
        //添加方法
        rw->methods.attachLists(&list, 1);
    }
    property_list_t *proplist = ro->baseProperties;
    if (proplist) {
    //添加属性
        rw->properties.attachLists(&proplist, 1);
    }

    protocol_list_t *protolist = ro->baseProtocols;
    if (protolist) {
    //添加协议
        rw->protocols.attachLists(&protolist, 1);
    }
    //添加协议【略】
}

流程总结

rw与ro

(class_rw_t *)(bits & FAST_DATA_MASK)

2019.7.26更新

对于class_rw_t 以及class_ro_t进一步理解

关于cache_t

cache

方法调用流程

CHPerson *person = [[CHPerson alloc] init];
[person test]
  1. 首先通过isa找到person对应的CHPerson类,先查看其中的cache_t里的缓存方法
  2. 如果找不到该test方法,就去查看bits中的rw的methods查找方法【如果找到了,调用,且添加到cache_t中】
  3. 如果在CHPerson里找不到,会查看CHPerson的父类,同样是先cache_t,后bits,如果查找到了,是存放在自己的cache里,不是父类的【注意!】
  4. 最后一直查看父类会到达NSObject根类,如果依然找不到就抛出异常

2019.8.3更新【ivar】

property和ivar

ivar

//ivar_t
struct ivar_t {
    int32_t *offset;
    const char *name;
    const char *type;
    uint32_t alignment_raw;
    uint32_t size;
};

property

struct property_t {
    const char *name;
    const char *attributes;
};

两者关系

Non Fragile ivars

img

遇到问题了

img

动态偏移

img
上一篇 下一篇

猜你喜欢

热点阅读