美文网首页
Objective-C 类

Objective-C 类

作者: MaZengyi | 来源:发表于2017-01-19 23:49 被阅读19次

    由于 Objc2.0 的改版, 很多旧的描述已经过时, 一下是对 Objc2.0 的总结

    Class

    Class 在 Runtime 中是对象的模型
    其在 Runtime 中的定义为是一个 objc_class 结构体

    typedef struct objc_class *Class;
    

    而 objc_class 的定义如下,

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

    因为 objc_class 继承与 objc_object 所以每个 Class 都有一个 isa 指针,而 isa 的类型是 isa_t 类型。

    isa 指针

    isa 表示这个对象是哪个类,
    isa 的数据结构是 isa_t, 而 isa_t 的结构描述是

    union isa_t 
    {
        isa_t() { }
        isa_t(uintptr_t value) : bits(value) { }
    
        Class cls;
        uintptr_t bits;
        ......
    };
    

    可以看出, 每个 isa 中都有一个 Class 类型的 cls 和 bits 字段。 而 cls 字段表示 isa 指向的 class

    类、父类、元类

    在网上众多文章中,都没具体提到 Class 为什么是对象,以及没说清到底 Class 是到底是类的描述还是实例对象。下面我们一起来了解一下到底什么是类。

    在 Runtime 中,类(Class)的概念和其他面向对象语言有点不同,这里的 Class 并不是一个对象的描述,而是在 Class 加载的时候,Runtime 生成的一块存在初始化好的 objc_class 结构体实例来表示一个 Class 在 Runtime 的描述, 这也解释了为什么 Class 本身也是一个对象,每个 class 都是独一无二的。

    父类:顾名思义就是一个类的所继承的类。在 objc_class 中 superclass 定义。

    元类:我们知道 isa 指针指向一个当前对象的类,而这个类也是对象,那么它的 isa 指向什么呢?这就是元类。元类的作用主要是用来存储查找类方法。

    下面我们通过具体实例来解释下对象在内存中如何表示:
    如:自定义一个 XXObject 类,

    1. Runtime 在加载 XXObject 的时候会初始化一个包含 XXObject 的 class 对象用来表示 XXObject 类,我们给它取个名字叫 rt_XXObject.
    2. 因为 rt_XXObject 也是一个对象(Class 本身也还是一个对象),所以它的 isa 也要指向一个对象,所以 Runtime 会生成类似步骤1中的内存对象,但是这个对象只存放类方法,这个类就是元类,并且将 rt_XXObject 的 isa 指向它,但是元类也是一个对象那它的 isa 指向哪儿,总不可能无限下去,于是 Apple 让元类的 isa 指向 rootMetaClass(根元类),这里是 NSObject 的 元类,而根元类的元类指向 nil 来形成一个闭环。
    3. 当我们创建对象,调用 [[XXObject alloc]init] 时,runtime 生成一个 class 对象,并将 isa 指针指向 rt_XXObject,表示这个对象是 XXObject 的实例。

    下面有张图可以加深理解


    objc-isa-class-diagra

    相关文章

      网友评论

          本文标题:Objective-C 类

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