msgSend 流程详解

简介: 1.编译阶段 用户调用一个普通函数[anObject doTings:things]; 编译器会把其编译为:objc_msgSend(anObject, @selector(doThings:), things); 注意:根据函数返回值的不同,编译器还会将其编译为objc_msgSend_st

1.编译阶段

用户调用一个普通函数
[anObject doTings:things];
编译器会把其编译为:
objc_msgSend(anObject, @selector(doThings:), things);
注意:根据函数返回值的不同,编译器还会将其编译为objc_msgSend_stret、objc_msgSend_fpret等。但是,实现大同小异。这里只以objc_msgSend为例进行讨论。

2.msgSend概述

objc_msgSend实现大致如下:
id objc_msgSend(id self, SEL _cmd, ...){
Class class = object_getClass(self;)
IMP imp = cache_lookup(c, _cmd);
if(!imp){
imp = class_getMethodImplementation(class, _cmd);
}
return imp ? imp(self, _cmd, ...) : 0
}

由此可见,其主要功能可分为获取函数imp和调用imp两块。

3.msgSend整体流程

screenshot


Step1. dispatch table中搜索selector的imp。这步大家应该都清楚,子类找不到,就去搜索父类,依次往上遍历。
注:dispatch table是编译时生成的selector与imp的对应表

Step2. 如果子类和所有父类的dispatch table中都没找到,就到动态解析。
很多人可能认为,这个曲折的寻找过程是必不可少的。其实并不是这样的。可以将子类中某个方法的imp直接设置成objc_msgForward,就可以直接进入转发流程。

Step3.函数调用
这里着重介绍下转发机制(__forwarding__)的实现。其代码大致如下:

screenshot

这里不做详细分析,简要说下我认为有用的几点:
a.为何有了forwardingInvoaction,还需要fowardingTarget?
因为fowardingTarget不涉及参数解析与封装,只是简单的把target替换下,就立马进入下一轮msgSend,所以效率较高,是首选。只有当涉及参数处理时,才有必要在forwardingInvoaction中干。

b.为什么forwardingInvoaction前,需要获取methodSignature?
单靠selector,无法完成对参数的解析,从而无法完成对target、selector和参数的打包。此时,需要获取method signature(包含参数、返回值的所有信息)来协助完成对参数的解析。


objc_msgForward和其他函数imp一样,都是函数指针
objc_msgForward和其他函数imp一样,都是函数指针
objc_msgForward和其他函数imp一样,都是函数指针
重要的事情说三遍

参考文献

[1] What's that Selector?
[2] Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法

目录
相关文章
|
测试技术 开发工具 UED
|
2月前
|
监控 机器人 数据安全/隐私保护
|
2月前
|
监控 安全 数据处理
了解阿里云 RPA:如何实现流程自动化
机器人流程自动化(RPA)是一种快速发展的技术,它可以帮助企业实现重复性任务的自动化,提高工作效率和准确性。阿里云 RPA 作为一款强大的 RPA 解决方案,为用户提供了一种简单而高效的方式来实现流程自动化。本文将介绍阿里云 RPA 的功能和特点,以及如何使用它来实现流程自动化。
|
9月前
|
JSON 前端开发 数据库
基于jsplumb构建的流程设计器
最近在准备开发工作流引擎相关模块,完成表结构设计后开始着手流程设计器的技术选型,调研了众多开源项目后决定基于jsplumb.js开源库进行自研开发,保证定制化的便捷性,相关效果图及项目地址如下
94 0
基于jsplumb构建的流程设计器
|
8月前
|
监控 关系型数据库 MySQL
架构基本流程
架构基本流程
|
数据采集 消息中间件 监控
数据预处-理用例流程介绍|学习笔记
快速学习数据预处-理用例流程介绍
67 0
数据预处-理用例流程介绍|学习笔记
|
XML Dubbo Java
服务注册流程分析01
在填充该 ServiceBean 的时候会将对应的那个声明了注解的 bean 设置到 ServiceBean 中。 剩下的流程放置到下一篇文章中
95 0
|
Dubbo Java 应用服务中间件
服务注册流程分析02
上一篇文章中、我们已经知道 Dubbo 会额外注册 ServiceBean 到 Spring 容器中、因为需要借助这个 ServiceBean 注册到服务中心
127 0
|
数据处理
freeModbus流程分析
freeModbus流程注解
1079 0
freeModbus流程分析
分享到支付宝集成流程
支付宝分享是指第三方移动应用通过接入该功能,让用户可以分享图片、网页至支付宝。可以通过支付宝分享,帮助移动应用通过社交快速传播,并能在传播中方便高效的提升购买转化率。 一、文档地址 官方文档地址:[url]https://docs.open.alipay.com/215/105279/[/url] 二、开发前准备工作 调用步骤:[url]https://openclub.alipay.com/read.php?tid=12194&fid=69[/url] 注意事项:1、不支持沙箱测试;2、不需签约,但需要添加功能;3、不支持第三方调用。
541 0