实例对象(objc_object)
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
/// A pointer to an instance of a class.
typedef struct objc_object *id;
这里的 id 被定义为一个指向 objc_object 结构体 的指针。从中可以看出 objc_object 结构体 只包含一个 Class 类型的 isa 指针。一个 Object(对象)唯一保存的就是它所属 Class(类) 的地址。
类对象(objc_class)
OC中的类是由 typedef struct objc_class *class
结构体表示的。
objc_class
结构体旧版本定义如下:
struct objc_class {
//isa指针
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
//父类指针
Class _Nullable super_class OBJC2_UNAVAILABLE;
//类的名称
const char * _Nonnull name OBJC2_UNAVAILABLE;
//版本
long version OBJC2_UNAVAILABLE;
//信息?
long info OBJC2_UNAVAILABLE;
//实例大小
long instance_size OBJC2_UNAVAILABLE;
//属性列表
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;
//方法列表
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;
//缓存
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;
//遵循的协议列表
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
在新版本定义如下:
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
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
,两个合一起就相当于
struct objc_class {
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_data_bits_t
结构体中data()
方法,bits & FAST_DATA_MASK
获取 class_rw_t
结构体
#define FAST_DATA_MASK 0x00007ffffffffff8UL
struct class_data_bits_t {
public:
class_rw_t* data() {
return (class_rw_t *)(bits & FAST_DATA_MASK);
}
}
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;
}
class_rw_t
结构体中存储有方法列表、属性列表、协议列表等。其中class_ro_t
结构体保存的是原信息,class_ro_t
结构体定义如下:
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize;//instance对象占用的空间
#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;
}
};
综上所述,在新版本的定义中类对象的结构如下图所示:
结构体里保存了指向父类的指针、类的名字、版本、实例大小、实例变量列表、方法列表、缓存、遵守的协议列表等,这个结构体存放的数据称为元数据(metadata),
此结构体的第一个成员变量也是isa指针,这就说明了Class本身其实也是一个对象,因此我们称之为类对象。
元类
对象(objc_object 结构体)的isa指针 指向的是对应的 类对象(object_class 结构体)。那么 类对象(object_class 结构体)的isa
指针 又指向类对象自身的Meta Class(元类)。
Meta Class(元类) 就是一个类对象所属的 类。一个对象所属的类叫做类对象,而一个类对象所属的类就叫做 元类
。
Runtime 中把类对象所属类型就叫做 Meta Class(元类),用于描述类对象本身所具有的特征,而在元类的 methodLists
中,保存了类的方法链表,即所谓的「类方法」。并且类对象中的 isa
指针指向的就是元类。每个类对象有且仅有一个与之相关的元类。
元类与类、实例之间的关系
通过上图我们可以看出整个体系构成了一个自闭环,struct objc_object
结构体实例它的isa指针指向类对象,
类对象的isa指针指向了元类,super_class
指针指向了父类的类对象,
而元类的super_class
指针指向了父类的元类,那元类的isa指针又指向了自己。