美文网首页
01--方法本质05--消息查找流程

01--方法本质05--消息查找流程

作者: 修_远 | 来源:发表于2020-06-15 16:59 被阅读0次

对方法的探索,全篇分六个章节

01-方法本质-方法初探

02-方法本质-objc_msgSend的使用

03-方法本质-面试题分析

04-方法本质-lookUpImpOrForward 介绍

05-方法本质-消息查找流程

06-方法本质-消息转发流程

五、消息查找流程(重点)

前言

这一章将会介绍消息的第一个流程——查找流程。

当调用一个方法的时候,系统是从哪里找到这个方法的?

[toc]

5.1 lookUpImpOrForward 准备条件

从源码中可以看到,有一个 retry:,retry的意思是重试,那么可以猜测出来下面的才是正真的流程,那上面的内容是什么呢?

retry上面的两段代码,_class_initializerealizeClass,不是初始化就是准备,可以猜测这里是一些变量的准备条件

再往上面走,看到有一个 runtimeLock。lock(); 方法,而且还有很多注释,说明这段代码在这个方法里面有很重要的作用。仔细扒一扒这些注释的含义,

  • 注释一:讲了运行时锁的作用,防止多线程发生资源抢夺

    runtimeLock在isrealize和isInitialized检查过程中被持有,以防止对并发实现的竞争。

  • 注释二:讲了为什么要添加运行时锁。举了一个例子,在缓存中搜索方法的时候(读操作),分类可以刷新缓存(写操作),同时对一块内存进行读写操作,它是受不了的。

    runtimeLock在方法搜索过程中保持,使方法查找+缓存填充原子相对于方法添加。否则,可以添加一个类别,但是会无限期地忽略它,因为在代表类别的缓存刷新之后,缓存会用旧值重新填充。

继续往上面走,有一个 return imp; 代码。这个方法本来就是查找一个方法的,能 return 的话,说明这个方法找到了。这里的代码很简单,就是从缓存里面找到了方法。

有趣的是这段代码的注释--// Optimistic cache lookup(乐观的缓存查找)。这就有意思了,什么叫乐观的,我们程序员讲究的是严谨的,要么能找到要么不能找到,既然是乐观的,我们就不用去分析他了。

再往上面走就是一些变量的创建,没什么好分析的。

到这里,我们对 lookUpImpOrForward 方法已经分析了一半了,下面来看另外一半流程。

5.2 lookUpImpOrForward 查找流程

5.2.1 lookUpImpOrForward 流程图

image

5.2.2 lookUpImpOrForward 流程分析

retry 开始分析

1、从类的缓存查找,如果找到IMP,则跳到Done,返回IMP
imp = cache_getImp(cls,sel);

2、从类的方法列表查找
Method meth = getMethodNoSuper_nolock(cls,sel);

  • 查找算法:二分查找
  • 如果找到,则填充缓存,跳到Done,返回IMP
    log_and_fill_cache(cls,meth->imp,sel,inst,cls);

遍历父类

for (Class curClass = cls->superclass;
              curClass != nil;
              curClass = curClass->superclass)

3、从父类的缓存查找
imp = cache_getImp(curClass,sel);

  • 如果在父类中找到方法,则将方法缓存到当前类,下次可以直接从缓存取
  • 跳到Done,返回IMP
    log_and_fill_cache(cls,imp,sel,inst,curClass);

4、从父类的方法列表查找
Method meth = getMethodNoSuper_nolock(curClass,sel);

  • 查找算法:二分查找
  • 如果找到,则填充缓存
  • 跳到Done,返回IMP
    log_and_fill_cache(cls,meth->imp,sel,inst,curClass);

5、方法动态决议流程
_class_resolveMethod(cls,sel,inst);

6、消息转发流程
imp = (IMP)_objc_msgForward_impcache;

5.3 总结

  1. 为什么分析 lookUpImpOrForward 方法。
  2. 怎么分析 lookUpImpOrForward 方法。
  3. retry 前做了什么事。
  4. retry 后的流程是什么样的。
  5. lookUpImpOrForward 查找流程图

相关文章

网友评论

      本文标题:01--方法本质05--消息查找流程

      本文链接:https://www.haomeiwen.com/subject/ucdhxktx.html