2016笔记——Runtime(四)

objc_msgSend函数的深入解析:

屏幕快照 2016-04-13 17.23.42.png

第一个参数是一个id类型的参数,可以为任何对象或者类。

第二个参数是一个SEL类型的参数。

那么SEL又是什么?

SEL是对方法的一种封装,展示的是方法名或者说是签名,方法的真正实现在IMP中,接下来我们看一下方法的链表是什么样子:

屏幕快照 2016-04-14 09.06.27.png

下面是重点了,我们仔细看一下在OC中传递一个消息的流程。

调用一个objc_msgSend( id receiver ,SEL selector ,...)方法系统执行的步骤:

1、

判断receiver是否为nil,如果是nil的话,则不往下执行,返回nil。这就是为什么在OC中向一个nil发送消息不会引起崩溃的原因。

2、

从方法的缓存中查找,被调用过的方法会存在缓存里面,每个类都会有一个表来存被调用过的方法,以便下次更快的调用。

3、

从本类的方法表(dispatch table)中查找方法selector,找到则写入缓存,返回方法。否则就到父类中查找方法,直到基类。如果找不到则执行方法的动态解析。

4、

方法的动态解析:调用+(BOOL)resolveInstanceMethod:(SEL)sel方法来查看是否能够返回一个selector,如果存在则返回selector。不存在则进入下一步。

5、

备用接收者:- (id)forwardingTargetForSelector:(SEL)aSelectro这个方法来询问是否有接收者可以接收这个方法,如果有人接收,则交给它处理,就好像什么都没发生过一样。

6、

方法的转发:如果到了这一步还不能够找到相应的Selector的话,就要进行完整的方法转发过程。调用方法-(void)forwardingInvocation:(NSInvocation*)anInvocation

7、

如果还没有找到方法就GG了,这时候就会抛出 unrecognized selector sent to instance 0x10001fdd0 的错误了。

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

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,814评论 0 9
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,656评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,148评论 1 32
  • 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的...
    西木阅读 30,649评论 33 466
  • 我们常常会听说 Objective-C 是一门动态语言,那么这个「动态」表现在哪呢?我想最主要的表现就是 Obje...
    Ethan_Struggle阅读 2,234评论 0 7