Bloodline's Blog Notes and thoughts from Bloodline

Objective-C的isa指针

Comments

前言

Objective-CNSObject是大多数类的根类。

@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

它有一个isa属性,类型是Class。isa是什么呢?Class又是什么呢?

isa

Class<objc.h>中的定义:

#if !OBJC_TYPES_DEFINED
/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

/// Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;
#endif

Class是一个objc_class结构类型的指针,id是一个 objc_object结构类型的指针。

再看<runtime.h>objc_class的定义:

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
	Class super_class; // 指向其父类
	const char *name; // 类名
	long version; // 类的版本信息,初始化默认为0,可以通过runtime函数class_setVersion和class_getVersion进行修改、读取
	long info; // 一些标识信息,如CLS_CLASS (0x1L) 表示该类为普通 class ,其中包含对象方法和成员变量;CLS_META (0x2L) 表示该类为 metaclass,其中包含类方法;
	long instance_size ; // 该类的实例变量大小(包括从父类继承下来的实例变量);
	struct objc_ivar_list *ivars; // 用于存储每个成员变量的地址
	struct objc_method_list **methodLists; // 与 info 的一些标志位有关,如CLS_CLASS (0x1L),则存储对象方法,如CLS_META (0x2L),则存储类方法;
	struct objc_cache *cache; // 指向最近使用的方法的指针,用于提升效率;
	struct objc_protocol_list *protocols; // 存储该类遵守的协议
#endif
  • isa:是一个Class类型的指针。每个实例对象有个isa的指针,他指向对象的类,而Class里也有个isa的指针,指向meteClass(元类)。元类保存了类方法的列表。当类方法被调用时,先会从本身查找类方法的实现,如果没有,元类会向他父类查找该方法。同时注意的是:元类(meteClass)也是类,它也是对象。元类也有isa指针,它的isa指针最终指向的是一个根元类(root meteClass)。根元类的isa指针指向本身,这样形成了一个封闭的内循环。
  • super_class:父类,如果该类已经是最顶层的根类,那么它为NULL
  • version:类的版本信息,默认为0。
  • info:供运行期使用的一些位标识。
  • instance_size:该类的实例变量大小。
  • ivars:成员变量的数组。
struct objc_ivar_list {
    int ivar_count;
#ifdef __LP64__
    int space;
#endif
    /* variable length structure */
    struct objc_ivar ivar_list[1];
};
  • methodLists:方法定义的数组。
struct objc_method_list {
    struct objc_method_list *obsolete;

    int method_count;
#ifdef __LP64__
    int space;
#endif
    /* variable length structure */
    struct objc_method method_list[1];
};
  • objc_cache:指向最近使用的方法,用于方法调用的优化。
  • protocols:协议的数组。

关于元类(meteClass)的补充:

核心规则:类的实例对象的isa指向该类;该类的isa指向该类的 metaclass。

通俗说法:成员方法记录在class method-list中,类方法记录在metaClass中。即instance-object的信息在class-object中,而class-object的信息在metaClass中。

各个类实例变量的继承关系: 继承关系

每一个对象本质上都是一个类的实例。其中类定义了成员变量和成员方法的列表。对象通过对象的isa指针指向类。

每一个类本质上都是一个对象,类其实是元类(meteClass)的实例。元类定义了类方法的列表。类通过类的isa指针指向元类。

所有的元类最终继承一个根元类,根元类isa指针指向本身,形成一个封闭的内循环。