OC底层原理二:OC对象的分类(实例对象、类对象、元类对象)

4 阅读2分钟

一、实例对象(instance object)

实例对象是使用类alloc出来的对象,每次调用alloc都会产生新的实例对象。

  1. 创建方法 NSObject* obj = [[NSObject alloc] init]; obj就是实例对象

  2. 存储信息 isa指针、其他成员变量的值(isa指针也是成员变量,实例对象只存储变量的值,而成员变量的类型和名称等信息保存在类对象)

二、类对象(class object)

  1. 获取方法 需导入#import <objc/runtime.h>

类对象的class方法返回self,所以[[NSObject class] class]方法返回的依然是类对象

实例对象的class方法,实际调用了object_getClass方法。 object_getClass方法:获取该对象的isa指针,如果传入实例对象,则返回类对象;如果传入类对象,则返回元类对象。

  1. 类型 类对象是一种结构体

  2. 存储信息 isa指针、superclass指针、属性列表、对象方法(或者叫实例方法)列表、协议列表、成员变量信息列表(类对象存储成员变量的类型和名称等信息,而变量的值存储在实例对象)等:

  3. 疑问 为什么实例方法、成员变量信息放在类对象中,而不是保存在实例对象中? 答: 因为这些信息是相对固定的,保存一份即可; 并且由实例对象调用,所以保存在类对象中; 如果保存在实例对象中,每创建一个实例对象,信息重复,不利于内存优化。

  4. 内存地址 一个类的类对象在内存中只有一份,打印上面类对象的地址,结果都一样:

三、元类对象(meta-class object)

  1. 获取方法 元类对象的获取方法:需导入#import <objc/runtime.h>

  2. 类型 和类对象一样,元类对象也是objc_class结构体

  3. 存储信息 isa指针、superclass指针、类方法等 由于元类对象和类对象的类型都是Class,所以它们的村粗结构是一样的,只是内容不一样而已。

  4. 内存地址 一个类的元类对象在内存中只有一份

  5. 验证元类对象的方法 class_isMetaClass(obj)