Objetive-C最基本的的东西就是它的消息机制。Objective-C运行时的最基本的东西就是 objc_msgSend, 它就是负责发送一个消息给对象的C函数。

 
当你写下面这样的代码时:  [tableView cellForRowAtIndexPath:indexPath];
 
编译器实际上把它转换成下面这样的C函数调用  objc_msgSend(tableView, @selector(cellForRowAtIndexPath:), indexPath);
 

objc_msgSend的返回类型是id. 如果你需要 让一个方法调用, 返回一个原始的对象(或者C结构体)而不是 对象指针, 那应该怎么办呢?

执行下面人为捏造的代码(因为一般不会直接调用msgSend),会返回一个编译器错误,因为类型不匹配

UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
CGRect rect = objc_msgSend(view, @selector(frame));

如果你将第2行,改成 [view frame]
编译器 不会 把它转换成 msgSend, 而是调用 objc_msgSend_stret

objc_msgSend_stret是一个objc_msgSend的替代版本, 用来返回一个结构体。stret就是 STruct RETurn的缩写。
另外一个相关的objc_msgSend_fret 返回一个Floating-pointer

 
函数声明

void objc_msgSend_stret(void *stretAddr, id theReceiver, SEL theSelector, ....)
 
几个特殊方法

objc_msgSend_stret
如果待发送的消息要返回结构体,那么可交由此函数处理。只有当CPU的寄存器能够容纳得下消息返回类型时,这个函数才能处理此消息。若是返回值无法容纳于CPU寄存器中(比如说返回的结构体太大了),那么就由另一个函数执行派发。此时,那个函数会通过分配在栈上的某个变量来处理消息所返回的结构体。

objc_msgSend_fpret
如果消息返回的是浮点数,那么可交由此函数处理。在某些架构的CPU中调用函数时,需要对“浮点数寄存器”(floating-point register)做特殊处理,也就是说,通常所用的objc_msgSend在这种情况下并不合适。这个函数是为了处理x86等架构CPU中某些令人稍觉惊讶的奇怪状况。

objc_msgSendSuper
如果要给超类发消息,例如[super message:parameter],那么就交由此函数处理。也有另外两个与objc_msgSend_stret和objc_msgSend_fpret等效的函数,用于处理发给super的相应消息。

 

 1、为了性能,objc_msgSend用汇编写成。存在于objc-msg-x86_64.s中。

  

 2、在上图代码中可以看到,objc_msgSend被分为2个过程:1)在cache中寻找SEL。2)在MethodTable寻找SEL。

 3、CacheLookup中,不断地拿SEL与cache中的缓存比较,比较失败,则跳转到 LCacheMiss标签继续在MethodTable中搜索。

  

  如果想手动查找cache,则需要调用_cache_getimp函数(汇编实现),此函数是个对外接口层,用于保存与准备环境。

  

  _cache_getImp在头文件中objc-private.h中,链接后objc/c代码可以直接调用。

  

 4、MethodTableLookup 是个接口层宏,主要用于保存环境与准备参数,来调用 __class_lookupMethodAndLoadCache3函数(此函数实现于objc-class.mm)。

  

 5、__class_lookupMethodAndLoadCache3函数也是个接口层(C编写),此函数提供相应参数配置,实际功能在lookUpMethod函数中。

  

 6、lookUpMethod函数实现遍历method_list_t,从子类开始,一直遍历到根类。此函数代码较大,不贴图了。文件在objc-class中。

最新文章

  1. MySQL4.0命令操作学习笔记
  2. Linux的学习日记
  3. Nodejs·内存控制
  4. Swift一些语法
  5. copy-mutableCopy
  6. JavaScript宝座:七大框架论剑
  7. js获取iframe的parent对象
  8. Python 知识点
  9. 4. c++ 静态 对象
  10. linux ln 命令(转载)
  11. git的使用及常用命令
  12. 关于json数据格式错误
  13. AvalonJS前端开发源码
  14. javaweb 发布目录
  15. 创建属于其他Session的进程
  16. hdu 4277 USACO ORZ dfs+hash
  17. PythonStudy——编程基础 Python Primary
  18. 理解HDFS高可用性架构
  19. C#关键字as出现的错误
  20. nopcommerce

热门文章

  1. FastAdmin 的 API 可以分级吗?
  2. 算法题:求一个序列S中所有包含T的子序列(distinct sub sequence)
  3. (转)Inno Setup入门(九)——修改安装过程中的文字显示
  4. 【转】Jmeter使用之常用函数介绍
  5. Java-Runoob-高级教程:Java 序列化
  6. Java-Runoob-面向对象:Java 多态
  7. 模块初识2-模块的默认保存路径Python36-32\\lib\\site-packages,Python36-32\,标准库和第三方库
  8. IDA Pro 权威指南学习笔记(十三) - 基本代码转换
  9. cisco 三层交换机通信
  10. django的实现异步机制celery