object-c的对象模型

类的对象模型组成

1.在runtime.h找到Class和objct的定义

typedef struct objc_class *Class;

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

可以看出class 和id都是一个Class的结构体,下面让我来看下class结构体有哪些结构

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class super_class                                        OBJC2_UNAVAILABLE;
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    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;

上面的可以看出class包含了两个主要的对象isa, super
类的实例对象(instace object)指向类对象(class)。类对象(class)的isa指针指向类结构称为元类(metaclass),元类保存类的static成员变量和static方法(+开头的方法),实例对象中的isa指向类对象(普通的class),
该结构存储了普通成员变量与普通的成员方法(-开头的方法)。

继承中的子类,父类,根类的关系

  • 规则1: 类的实例对象is指向该类,该类的isa指向该类的元类(metaclass)
  • 规则2: 类的super_class执行该类,如果该类为根类(nsobject)则值为NULL
  • 规则3: metaclass的isa指向根类的metaclass,如果该类为根类(nsobjct)则指向本身
  • metaclass的super_class指向父metaclass,如果该metaclass是根metaclass则指向metaclass对应的类

例子,child-->father-->nsobject,对象的关系图如下

Paste_Image.png

class的结构变量

  1. objc_ivar_list *ivars 该类是class普通类保存普通成员变量,是metaclass保存类的static成员变量
  2. objc_method_list **methodLists,该类是class普通类是成员方法(-开头方法),是metaclass类方法(方法)
  3. objc_cache *cache,用于存储最近调用的方法缓存,下次调用直接使用,不用再遍历查找

class的方法的重写和寻址

  1. methodLists保存了成员方法,如果该类是子类,并且重写了父类方法,重写方法会在此列表中。子类调用方法时,会在cache中查找,找到该方法的缓存,直接返回imp, 如果没找到去类的methodLists的列表找,如果能找到,返回,并加入cache,如果找不到就会往superclass的methodLists方法中寻找,往上递推。找不到就进入到动态决策,和消息转发

+ (void)initialize方法调用层级

Paste_Image.png
IMP _class_lookupMethodAndLoadCache3(id obj, SEL sel, Class cls)
{
// 根类的id,nsojbet ,sel =alloc, cls = 自己类本身
    return lookUpImpOrForward(cls, sel, obj, 
                              YES/*initialize*/, NO/*cache*/, YES/*resolver*/);
}

runtime的cache机制

为了加速消息发送的进程,runtime缓存了selector和曾经使用的方法实现的映射。每个类都有自己的缓存,它能缓存selector和祖先类中的方法实现映射。在查找派发表之前,消息发送系统会先检查接收者的缓存(理论上说,用过的方法实现,不久会再用到)。如果缓存命中,则消息发送几乎和函数调用一样快。一旦程序运行时间足够长,缓存有了充足的“热身”【warm up】,那么几乎所有的查找都能在缓存中完成。随着程序的运行,缓存也会不断添加新的映射。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容