iOS Class中的实例、类、元类、isa

实例对象(id)

实例对象是咱们对类对象alloc或者new操做时所建立的,在这个过程当中会拷贝实例所属类的成员变量,但并不拷贝类定义的方法。缓存

/// 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;
复制代码

objc_object这个结构体只有一个isa变量,指向实例对象所属的类。任何带有以指针开始并指向类结构的结构均可以被视做objc_object, 对象最重要的特色是能够给其发送消息。bash

类(Class)

typedef struct objc_class *Class;
复制代码

因而可知 ,Class是指向C的结构体objc_class的指针,咱们再看一下objc_class的定义函数

元类(objc_class)

struct objc_class {
    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
复制代码
  • isa指针是和Class同类型的objc_class结构指针,类对象的指针指向其所属的类,即元类。元类中存储着类对象的类方法,当访问某个类的类方法时会经过该isa指针从元类中寻找方法对应的函数指针。
  • super_class为该类所继承的父类对象,若是该类已是最顶层的根类(如NSObject或NSProxy), 则 super_class为NULL。
  • ivars是一个指向objc_ivar_list类型的指针,用来存储每个实例变量的地址。
  • info为运行期使用的一些位标识,好比:CLS_CLASS (0x1L)表示该类为普通类, CLS_META (0x2L)则表示该类为元类。
  • methodLists用来存放方法列表,根据info中的标识信息,当该类为普通类时,存储的方法为实例方法;若是是元类则存储的类方法。
  • cache用于缓存最近使用的方法。系统在调用方法时会先去cache中查找,在没有查找到时才会去methodLists中遍历获取须要的方法。

isa

是一个Class 类型的指针,每一个实例对象有个isa的指针,他指向对象的类,而Class里也有个isa的指针, 指向meteClass(元类)spa

实例、类、元类、isa 关系图:

因而可知,在给实例对象或类对象发送消息时,寻找方法列表的规则为:指针

  • 当发送消息给实例对象时,消息是在寻找这个对象的类的方法列表(实例方法)
  • 当发送消息给类对象时,消息是在寻找这个类的元类的方法列表(类方法)

全部元类都有一个根元类,好比全部NSObject的子类的元类都会以NSObject的元类做为他们的类。全部的元类使用根元类做为他们的类,根元类的元类则就是它本身,也就是说根元类的isa指针指向他本身。code

总结:

object_getClass(实例对象) == [实例对象 class]
[类对象 class] == 类对象
object_getClass(类对象) == 类对象的isa == 元类
object_getClass(类对象) != [类对象 class]
复制代码
相关文章
相关标签/搜索