runtime各种数据结构

runtime各种数据结构

对象

struct objc_object {
private:
    isa_t isa;

public:

    // ISA() assumes this is NOT a tagged pointer object
    Class ISA();

    // getIsa() allows this to be a tagged pointer object
    Class getIsa();
    ...
}

所以说,只要是oc对象就有isa指针,但是这句话也不完全对

并不是所有的oc对象都有isa指针,例如Tagged Pointer对象没有isa指针,具体可以看这个文章深入理解Tagged Pointer

isa指针是指向一个类对象,为啥说的类对象,我们接着看类的数据结构

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    ...
}

类的结构体也是继承对象的,所以说类也是一个对象

这里理解可以看下

元类的文章,理解下元类,实例对象,类对象,元类对象

协议

struct protocol_t : objc_object {
    const char *mangledName;
    // 这个协议遵循的协议
    // 比如我们定义协议一般会xxDelete
    struct protocol_list_t *protocols;
    // 下面几个看命名就知道什么意思了
    method_list_t *instanceMethods;
    method_list_t *classMethods;
    method_list_t *optionalInstanceMethods;
    method_list_t *optionalClassMethods;
    property_list_t *instanceProperties;
    ...
}

1.协议的结构体也是继承objc_object,说明协议也是对象

2.mangledName是源于c++的命名重整技术,可以这样简单理解,c++之所以可以方法重载是基于命名重整这个技术

print(int i)
print(char c)

这个技术简单理解,就是编译器,在底层重新给方法命名,比如上面的print,在底层可能会生成i_printc_print

分类

struct category_t {
    // 所属的类名,而不是Category的名字
    const char *name;
    // 所属的类,这个类型是编译期的类,这时候类还没有被重映射
    classref_t cls;
    // 实例方法列表
    struct method_list_t *instanceMethods;
    // 类方法列表
    struct method_list_t *classMethods;
    // 协议列表
    struct protocol_list_t *protocols;
    // 实例属性列表
    struct property_list_t *instanceProperties;
    // Fields below this point are not always present on disk.
    // 类属性列表
    struct property_list_t *_classProperties;

    method_list_t *methodsForMeta(bool isMeta) {
        if (isMeta) return classMethods;
        else return instanceMethods;
    }

    property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};

因为没有成员变量列表,所以分类不可以添加成员变量,但是因为有属性列表,所以可以添加属性

我们这里还发现了一个类属性列表_classProperties,
这个的用法是
@property (class, nonatomic, copy) NSUUID *identifier;

如果这样声明,xcode不会自动生成set和get方法,你得自己实现,而且你实现的get和set方法是类方法哦

这个是为了跟swift交互诞生的

属性

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

// 测试代码

@property (nonatomic, copy) NSString *string;


objc_property_t t = class_getProperty([self class],"string");
const char *name = property_getName(t);
const char *att = property_getAttributes(t);
NSLog(@"name:%s,att:%s",name, att);

// 输出
name:string,att:T@"NSString",C,N,V_string

T代表类型@"NSString" 参考Type Encodings

C代表copy

N代表nonatomic

V代表实例变量_string

方法

struct method_t {
    // 方法编号
    SEL name;
    // 参数和返回类型encode
    const char *types;
    // 函数指针
    IMP imp;
    // 根据方法名进行方法排序(这个我也搞不懂用途)
    struct SortBySELAddress :
        public std::binary_function
    {
        bool operator() (const method_t& lhs,
                         const method_t& rhs)
        { return lhs.name < rhs.name; }
    };
};

成员变量

struct ivar_t {
    int32_t *offset; // 偏移
    const char *name; // 名字
    const char *type; // 类型
    // alignment is sometimes -1; use alignment() instead
    uint32_t alignment_raw; // 对齐
    uint32_t size; // 大小

    uint32_t alignment() const {
        if (alignment_raw == ~(uint32_t)0) return 1U << WORD_SHIFT;
        return 1 << alignment_raw;
    }
};

你可能感兴趣的:(runtime各种数据结构)