美文网首页初见
iOS进阶专项分析(四)、类的结构

iOS进阶专项分析(四)、类的结构

作者: 溪浣双鲤 | 来源:发表于2020-06-21 11:59 被阅读0次

直接开搞,打开objc源码, 搜索Class, 发现Class实质上是结构体objc_class的重定义, 换句话说类的本质就是结构体。继续深入,找到object_class结构体的定义部分:(objc_objectid类型的, 所以这里就找到底了)

struct objc_class : objc_object {
    // Class ISA;
    Class superclass;
    cache_t cache;             // formerly cache pointer and vtable
    class_data_bits_t bits;    // class_rw_t * plus custom rr/alloc flags

    class_rw_t *data() { 
        return bits.data();
    }
    void setData(class_rw_t *newData) {
        bits.setData(newData);
    }
    
    ...
    
}

这里我们可以看出类的结构中主要包含isasuperclasscachebits以及一个bits.data, 可以看出类的数据都存在bits.data属性中,继续研究这个属性,发现这个属性是class_rw_t类型的,我们继续查看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;
    
    ...
    
}

发现这里面存的有方法methods,属性properties,协议protocols,还有一个类型为class_ro_t的文件,注意这个文件是用const进行修饰的,也就是说这个文件是不可以进行更改,是一个只读的文件!我们继续查看这个类型class_ro_t的结构,发现了这个文件里面主要包含下面这些成员变量

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
#ifdef __LP64__
    uint32_t reserved;
#endif

    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;
    }
};

到这里,按照源码一层层深入,类的结构已经大致查看完了,思维导图总结如下:

OC类的结构.png

看完类的结构,我们需要注意一个细节:

class_ro_t类里面的属性成员变量ivars是用const修饰的!也就是说,在类的结构中,ivars这个属性是不可更改的,如果使用Runtime的API注册和实现一个类,必须注意添加成员变量的顺序

    //1、自定义一个类
    Class BMClass = objc_allocateClassPair([NSObject class], @"BMClass", 0);
    //2、给类添加一个成员变量ivar
    NSString * name = @"name";
    class_addIvar(BMClass, name.UTF8String, sizeof(id), log2(sizeof(id)), @encode(id));
    //3、注册这个类
    objc_registerClassPair(BMClass);

添加成员变量class_addIvar操作必须要在类的注册objc_registerClassPair之前,如果类已经注册完毕之后,ivar就添加不进去了!会导致你获取这个成员变量获取不到!这也是一个常见的知识坑点

溪浣双鲤的技术摸爬滚打之路

相关文章

  • iOS进阶专项分析(四)、类的结构

    直接开搞,打开objc源码, 搜索Class, 发现Class实质上是结构体objc_class的重定义, 换句话...

  • 类结构之cache分析

    背景 前面我们在分析ios类结构过程,在oc类结构那点事(四)中我们了解到class有几个关键属性,其中bits信...

  • iOS类结构:cache_t分析

    一、cache_t 内部结构分析 1.1 在iOS类的结构分析中,我们已经分析过类(Class)的本质是一个结构体...

  • iOS-底层分析之类的结构分析

    类的结构分析 本文主要分析iOS中的类以及类的结构,下面我们通过一个例子来探索类的结构 我们定义一个WPerson...

  • iOS 类的结构分析(下)

    在上一篇 iOS 类的结构分析(上) 分析了类的结构、isa 的走位以及类的内存分布(属性列表&实例方法列表),这...

  • 四、iOS-类的结构分析

    一、类的探究 我们从上一篇文章iOS中的isa分析对象的时候已经过渡到类了,提到了 对象,类,元类,根元类等概念,...

  • iOS底层之cache_t探究

    我们在iOS底层之类的结构分析分析了类的内部结构,而类的C/C++底层实际是objc_class结构体,其中包含了...

  • [iOS] 类 & 类结构分析

    1. 类的分析 1.1 元类的引入 我们可能之前已经知道类其实也是一个对象,类的 isa 指针指向的是它的元类,...

  • iOS 类结构分析

    前言 通过本篇文章可以了解1.isa的走位2.类结构的分析3.什么是元类4.supclass的走位5.objc_c...

  • iOS类结构分析

    本文主要来探索一下iOS中类的结构,作为一个iOS开发者,我们有必要去了解关于类的底层知识。下面开始我们的探索。 ...

网友评论

    本文标题:iOS进阶专项分析(四)、类的结构

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