Bird * aBird = [[Bird alloc] init];

[aBird fly];

中对 fly 的调用,编译器通过插入一些代码,将之转换为对方法具体实现 IMP 的调用,这个 IMP 是通过 在 Bird 的类结构中的方法链表中查找名称为 fly 的 选标 SEL 对应的具体方法找到实现的。

那么编译器插入了什么代码?如果在方法链表中没有找到对应的 IMP 又会如何 ?
  • 消息函数 obj_msgSend:

编译器会将消息转换为对消息函数 objc_msgSend 的调用,该函数有两个主要的参数:消息接收者 id 和

消息对应的方法选标 SEL, 同时接收消息中的任意参数: id objc_msgSend(id theReceiver, SEL theSelector, ...)

如上面的消息 [aBird fly]会被转换为如下形式的函数调用: objc_msgSend(aBird, @selector(fly));

该消息函数做了动态绑定所需要的一切工作:
1,它首先找到 SEL 对应的方法实现 IMP。因为不同的类对同一方法可能会有不同的实现,所以找到的方法实现依赖于消息接收者的类型。
2, 然后将消息接收者对象(指向消息接收者对象的指针)以及方法中指定的参数传递给方法实现 IMP。

3, 最后,将方法实现的返回值作为该函数的返回值返回。

在方法中可以通过 self 来引用消息接收者对象,通过选标_cmd 来引用方法本身。在下面的例 子中,_cmd 指的是 strange 方法,self 指的收到 strange 消息的对象。


- strange {
id target = getTheReceiver();
SEL method = getTheMethod();
if (target == self || mothod == _cmd)
return nil;
return [target performSelector:method];
}
  • 查找 IMP 的过程:

前面说了,objc_msgSend 会根据方法选标 SEL 在类结构的方法列表中查找方法实现 IMP。这里头有一 些文章,我们在前面的类结构中也看到有一个叫 objc_cache *cache 的成员,这个缓存为

OC之消息调用过程的更多相关文章

  1. WebViewJavascriptBridge源码探究--看OC和JS交互过程

    今天把实现OC代码和JS代码交互的第三方库WebViewJavascriptBridge源码看了下,oc调用js方法我们是知道的,系统提供了stringByEvaluatingJavaScriptFr ...

  2. JS与原生OC/Swift相互调用总结

    代码地址如下:http://www.demodashi.com/demo/12754.html JS-OC-Swift JS和OC/Swift相互调用,主要总结了JS和OC交互的三种方式 1.使用UI ...

  3. FormatMessage与GetLastError配合使用,排查windows api调用过程中的错误

    前一段时间在学习windows api调用过程中,遇到过一些调用错误或者程序没能显示预期的结果,或者直接出现vc运行时错误. 这对新手来说是司空见惯的事,因为不太熟悉难免会出错,出错的信息如果能显示很 ...

  4. Hbase的WAL在RegionServer基本调用过程

    版权声明:本文由熊训德原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/221 来源:腾云阁 https://www.qclo ...

  5. 对发给Application.Handle消息的三次执行(拦截)消息的过程

    unit Main; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms ...

  6. RocketMQ源码 — 三、 Producer消息发送过程

    Producer 消息发送 producer start producer启动过程如下图 public void start(final boolean startFactory) throws MQ ...

  7. RPC原理及其调用过程

    远程过程调用,简称为RPC,是一个计算机通信协议,它允许运行于一台计算机的程序调用另一台计算机的子程序,而无需额外地为这个交互作用编程. RPC与传统的HTTP对比 优点: 1. 传输效率高(二进制传 ...

  8. Dubbo 源码分析 - 服务调用过程

    注: 本系列文章已捐赠给 Dubbo 社区,你也可以在 Dubbo 官方文档中阅读本系列文章. 1. 简介 在前面的文章中,我们分析了 Dubbo SPI.服务导出与引入.以及集群容错方面的代码.经过 ...

  9. Dubbo学习(六) dubbo 架构图 以及调用过程

    一.Dubbo结构图   duubo结构图 我们解释以下这个架构图:Consumer服务消费者,Provider服务提供者.Container服务容器.消费当然是invoke提供者了,invoke这条 ...

随机推荐

  1. Spark编程模型及RDD操作

    转载自:http://blog.csdn.net/liuwenbo0920/article/details/45243775 1. Spark中的基本概念 在Spark中,有下面的基本概念.Appli ...

  2. C# lock关键词/lock语句块、线程锁

    一.lock关键词说明 1. lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁. 2. lock 语句块锁定,功能等同于 Monitor.Enter(obj): ...

  3. http://www.cnblogs.com/ycxyyzw/archive/2012/07/31/2616951.html

    http://www.cnblogs.com/ycxyyzw/archive/2012/07/31/2616951.html

  4. NOIP2010-普及组初赛C语言解析

    第十六届全国青少年信息学奥林匹克联赛初赛试题 一.单项选择题 (共20题,每题1.5分,共计30分.每题有且仅有一个正确选项.) 1.2E+03表示(  D  ). A.2.03          B ...

  5. hdu1536Nim

    sg函数打表的基础应用,第一道ac的sg函数打表题纪念下,直接上代码: hdu1536题目连接 #include<iostream> #include<cstdio> #inc ...

  6. reids配置参数详解

    转自:http://www.jb51.net/article/60627.htm reids配置参数详解 #daemonize no  默认情况下, redis 不是在后台运行的,如果需要在后台运行, ...

  7. ECOS-LNMP ZendGuard

    因为ECOS产品加密后依赖PHP Zendguard运行(基于PHP5.3加密)  备注: Shopex485商城基于php5.2进行加密 URL:http://www.zend.com/en/pro ...

  8. C++把引用作为返回值

    当返回一个引用时,要注意被引用的对象不能超出作用域.所以返回一个对局部变量的引用是不合法的,但是,可以返回一个对静态变量的引用. int& func() { int q; //! return ...

  9. Ubuntu 14.0 升级内核到指定版本

    1.卸载现有内核sudo apt purge linux-headers-* linux-headers-*-generic linux-image-*-generic linux-image-ext ...

  10. iOS蓝牙开发

    蓝牙常见名称和缩写 MFI ======= make for ipad ,iphone, itouch 专们为苹果设备制作的设备 BLE ==== buletouch low energy,蓝牙4.0 ...