iOS 底层原理02: 类,对象

一、对象的种类

OC中对象分为三种:

  • instance对象(实例对象): 通过类alloc出来的对象是实例对象, 每次alloc都会生成一个新的实例对象.

实例对象主要存储的信息包括: isa指针, 其他成员变量等

  • class对象(类对象): 类对象在内存中只会存储一份.

类对象主要存储的信息包括: isa指针, superclass 指针, 类的属性信息, 类的对象方法, 类的协议信息, 类的成员变量信息等

  • meta-class(元类对象): 元类对象与类对象的结构类似, 在内存中也只有一份

元类对象主要存储的信息包括: isa指针, superclass指针, 类的类方法等

二、类对象的源码分析

在objc源码中, 我们可以找到类对象的实现代码, 核心代码如下:

struct objc_class : objc_object {

    // Class ISA; isa指针 继承自objc_object
    Class superclass; // superclass 指针
    class_data_bits_t bits;    // 核心信息

    class_rw_t *data() const {
        return bits.data();
    }
    // .... 其他代码
};
复制代码

我们可以看到, data()函数返回的是 class_rw_t 类型, 继续探究

struct class_rw_t {
    // ...
private:
  
    // 获取当前类 是ro 或者是 rwe
    const ro_or_rw_ext_t get_ro_or_rwe() const {
        return ro_or_rw_ext_t{ro_or_rw_ext};
    }
    // ...

public:
    // rw 的扩展
    class_rw_ext_t *ext() const {
        return get_ro_or_rwe().dyn_cast<class_rw_ext_t *>(&ro_or_rw_ext);
    }
    // 获取当前类的 class_rw_ext_t, 在Category加载时用到
    class_rw_ext_t *extAllocIfNeeded() {
        auto v = get_ro_or_rwe();
        if (fastpath(v.is<class_rw_ext_t *>())) {
            return v.get<class_rw_ext_t *>(&ro_or_rw_ext);
        } else {
            return extAlloc(v.get<const class_ro_t *>(&ro_or_rw_ext));
        }
    }
    // ro 成员变量
    const class_ro_t *ro() const {
        auto v = get_ro_or_rwe();
        if (slowpath(v.is<class_rw_ext_t *>())) {
            return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->ro;
        }
        return v.get<const class_ro_t *>(&ro_or_rw_ext);
    }
    // 根据 ro_or_rwe(), 返回rw_ext的methods成员 或 ro_t 的baseMethods
    const method_array_t methods() const {
        auto v = get_ro_or_rwe();
        if (v.is<class_rw_ext_t *>()) {
            return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->methods;
        } else {
            return method_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext)->baseMethods()};
        }
    }
    // 根据 ro_or_rwe(), 返回rw_ext的properties成员 或 ro_t 的baseProperties
    const property_array_t properties() const {
        auto v = get_ro_or_rwe();
        if (v.is<class_rw_ext_t *>()) {
            return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->properties;
        } else {
            return property_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext)->baseProperties};
        }
    }
    // 根据 ro_or_rwe(), 返回rw_ext的protocols成员 或 ro_t 的baseProtocols
    const protocol_array_t protocols() const {
        auto v = get_ro_or_rwe();
        if (v.is<class_rw_ext_t *>()) {
            return v.get<class_rw_ext_t *>(&ro_or_rw_ext)->protocols;
        } else {
            return protocol_array_t{v.get<const class_ro_t *>(&ro_or_rw_ext)->baseProtocols};
        }
    }

    // ...
};
复制代码

那么我们看下 class_rw_ext_t 分别是什么class_ro_t

// class_rw_ext_t
struct class_rw_ext_t {
    class_ro_t_authed_ptr<const class_ro_t> ro; // class_ro_t
    method_array_t methods; // 方法列表
    property_array_t properties; // 属性列表
    protocol_array_t protocols; // 协议列表
    // ...
};

// class_ro_t
struct class_ro_t {
    // ...
    void *baseMethodList;  // 方法列表
    protocol_list_t * baseProtocols; // 协议列表
    const ivar_list_t * ivars;  // 成员变量列表
    property_list_t *baseProperties; // 属性列表
    
    // ...
};
复制代码

可以看到, 类对象的主要信息, 都存在了 class_rw_ext_t 和 class_ro_t 两个结构体中

三、isa指针, superclass指针分析

  • isa指针: object_getClass 函数返回的就是isa指针, 我们可以通过这个函数来分析

    Class object_getClass(id obj)
    {
        if (obj) return obj->getIsa();
        else return Nil;
    }
    复制代码
    • Person相关isa指针

    Person相关isa指针

    • NSObject相关isa指针

    NSObject相关isa指针

根据我们的实验, 可以总一下:

实例对象的isa -> 类对象, 类对象的isa -> 元类对象
元类对象的isa -> 根元类(NSOject) 根元类的isa -> 自身

  • superclass指针

superclass指针

总结如下:

子类的superclass -> 父类对象
父类对象的superclass -> NSObject
NSObject的superclass -> nil

  • isa 和superclass 指针的总结图如下:

isa 和superclass 指针

  • 方法调用顺序

    根据isa指针的指向, 我们就可以猜到, iOS 方法的调用顺序如下:

    1. 实例方法:

    实例对象的isa指针指向类对象, 所以先在类对象的methods列表中找, 找不到则去类对象的superclass中找, 最终到找到NSObject

    1. 类方法:

    类对象的isa指针指向元类对象, 所以先在元类对象的methods列表中找, 找不到则去元类对象的superclass中找, 最终找到NSObject

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享