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

2020-06-15  本文已影响0人  修_远

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

01-方法本质-方法初探

02-方法本质-objc_msgSend的使用

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

04-方法本质-lookUpImpOrForward 介绍

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

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

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

前言

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

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

[toc]

5.1 lookUpImpOrForward 准备条件

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

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

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

继续往上面走,有一个 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);

遍历父类

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

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

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

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

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

5.3 总结

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

猜你喜欢

热点阅读