OC语言里,每一个类实例对象是一个指向objc_object结构体的指针,每一个类对象是一个指向objc_class结构体的指针。在objc_object结构体中仅有一个isa指针成员。
/// Represents an instance of a class.
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
而在objc_class结构体中,除了isa指针之外它还有例如name(类名)、version(版本)、ivars(成员变量链表)、methodLists(方法链表)等等其它成员。
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; // 父类
const char *name OBJC2_UNAVAILABLE; // 类名
long version OBJC2_UNAVAILABLE; // 类的版本信息,默认为0
long info OBJC2_UNAVAILABLE; // 类信息,供运行期使用的一些位标识
long instance_size OBJC2_UNAVAILABLE; // 类的实例变量大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 类的成员变量链表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定义的链表
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法缓存
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 协议链表
#endif
} OBJC2_UNAVAILABLE;
那么问题来了,为什么objc_object结构体里面只有一个isa指针成员呢?只有这一个成员我们怎么能知道这个类的其他信息呢?
这个原因还是得从这个isa指针说起。我们知道,在OC中,每一个isa指针都指向它的元类,其中类实例对象的元类是类对象自己。这样一来,就会发现:类对象的isa指针指向它的类,而类的isa指针又指向这个类的元类,最后指向根元类(也就是我们的NSObject,它的元类是他自己本身)。所以,我们一旦知道了这个类实例对象的一个isa指针,我们就会知道这个类的属性方法等其他所有信息。