iOS 为何使用runtime方法交换多次后却能按照交换顺序依次执行代码逻辑?
题目: 假设我们有一个ViewController,
Category A(ViewController),
Category B(ViewController),
Category C(ViewController)
4个文件, 其中3个category中都实现了自定义viewDidLoad方法, 会对ViewController中的ViewDidLoad方法进行方法替换, 那么依次替换后(A B C)的方法执行顺序是什么呢?
记method_exchangeImplementations(Method _Nonnullm1, Method _Nonnullm2) 方法多次执行的代码执行逻辑.
假设我们的方法替换由我们指定的一个category D来完成3次交换过程,代码如下图

那么接下来我们就详细来探究一下每次追加一个方法交换,会对原方法有什么改变。
1. IMP方法实现交换
第一趟: 交换 原方法 和 A

ViewController的原方法如下

在category A中方法如下:

交换后类实例方法和IMP的指向如下:

方法调用:
交换后, 调用class 0(ViewController)的selector0, 会调用category A的IMP1, 既打印 “extension A viewDidLoad”, 然后调用了category A的Sel, 就会去执行 class 0(ViewController)的IMP, 既打印 “origin viewDidLoad method”;
控制台打印如下:

接下来追加方法交换: 在原有方法交换基础上 追加 交换原方法 和 B

在category B中方法如下:

交换后类实例方法和IMP的指向如下:

代码执行: 执行Sel0—>IMP2—>SelB—>IMP1—>SelA—>IMP, 所以控制台输入顺序为 B A 0
控制台输出如下:

继续追加方法交换: 在原有方法交换基础上 追加 交换原方法 和 C

在category C中方法如下:

交换后类实例方法和IMP的指向如下:

代码执行: 先执行Sel0-->IMP3—>SelC—>IMP2—>SelB—>IMP1—>SelA—>IMP, 所以控制台输入顺序为 C B A 0
控制台输出如下:

由此可以推理出来:
我们依次追加n个对原方法交换, 那么class 0对应的Sel0执行的IMP会偏移指向最后一个方法交换的Sel, 那么就会按照交换前后顺序执行逻辑.
Demo地址: https://github.com/Winerywine/MethodExchange.git
iOS 为何使用runtime方法交换多次后却能按照交换顺序依次执行代码逻辑?的更多相关文章
- iOS运行时Runtime浅析
运行时是iOS中一个很重要的概念,iOS运行过程中都会被转化为runtime的C代码执行.例如[target doSomething];会被转化成objc)msgSend(target,@select ...
- iOS运行时 -- Runtime(摘抄自网络)
运行时(iOS) 一.什么是运行时(Runtime)? 运行时是苹果提供的纯C语言的开发库(运行时是一种非常牛逼.开发中经常用到的底层技术) 二.运行时的作用? 能获得某个类的所有成员变量 能获得某个 ...
- iOS:学习runtime的理解和心得 (转)
Runtime是想要做好iOS开发,或者说是真正的深刻的掌握OC这门语言所必需理解的东西.最近在学习Runtime,有自己的一些心得,整理如下, 一为 查阅方便 二为 或许能给他人一些启发, 三为 希 ...
- iOS - 回顾总结Runtime原理及使用
runtime简介 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时.也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的 ...
- iOS开发系列-Runtime运用场景
概述 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的. 调用runtimeAPI需要导入都文件#impor ...
- iOS:学习runtime的理解和心得
http://www.cocoachina.com/ios/20150901/13173.html 作者:兴宇是谁 授权本站转载. Runtime是想要做好iOS开发,或者说是真正的深刻的掌握OC这门 ...
- iOS开发之Runtime使用
runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C语言,函数的调用在编译的时候会决定调用哪个函数. 对于OC的函数,属于动态 ...
- iOS中利用 runtime 一键改变字体
1.准备 我们新建一个项目名叫ChangeFont,然后我就随便找了个名叫loveway.ttf的字体库拖进去,里面的工程目录大概就是这样的 目录 现在我们就简单的直接在storyboard上拖了一个 ...
- IOS 高级开发 runtime(二)
二.移魂大法 使用runtime还可以交换两个函数.先贴上代码和执行结果. #import <Foundation/Foundation.h> @interface DZLPerson : ...
随机推荐
- ASP.NET Aries 高级开发教程:表单检测字段是否已存(番外篇)
前言: 昨天刚好有人问了这个问题,因此就针对这个问题,补上一篇吧. 正文: 如图:在用户编辑列表中,用户名是会自动检测是否已存在的. 具体对应的Html内容如下: <label><e ...
- 基于H7的串口WIFI模块ESP8266的TCP客户端例子和操作说明(AP兼STA模式)
说明: 1.如果不熟悉网络的话,等我这几天更新V7用户手册的ESP8266章节,如果熟悉的话,直接操作即可,这里将操作说明发出来. 2.串口WIFI是采用的AT指令操作,简单易用,指令手册在这个帖子里 ...
- js的cookies及html5的localStorage、sessionStorage
1.首先,理解什么是cookies? cookies:存储在客户端,数据量小的,会过期的数据,以字符串形式存储 cookie操作代码示例: <script> window.onload = ...
- C# 使用.net core 驱动树莓派的IO信号
如何使用.net core来驱动树莓派的IO信号?是我们的实际项目需求中,可能就会有这种小项目,我们要输出一个IO信号,此处我们拿了树莓派4做测试 一共有两排引脚,引脚的顺序定义及功能如下: 我们就参 ...
- mysql的锁机制详解
这段时间一直在学习mysql数据库.项目组一直用的是oracle,所以对mysql的了解也不深.本文主要是对mysql锁的总结. Mysql的锁主要分为3大类: 表级锁:存储引擎为Myisam.锁住整 ...
- Java 多线程应知应会
请简单说说 synchronized 关键字的底层原理 java 说到多线程绝对绕不开 synchronized,很多 java 工程师对 synchronized 是又爱又恨.为什么呢?主要原因包括 ...
- Prism_Composite Commands(3)
Composite Commands 在许多情况下,视图模型定义的命令将绑定到关联视图中的控件,以便用户可以直接从视图中调用该命令.但是,在某些情况下,您可能希望能够从应用程序UI的父视图中的控件调用 ...
- 用js传递当前页面的url,丢失了&后面的参数 解决办法
问题:因为登陆是用ajax传值的,在哪个页面点击登陆的,登陆成功跳到再跳回那个页面,之前直接传递的是 /index_do.php?gourl=" +location.href这样传递的,但是 ...
- 【Spring Cloud】Spring Cloud Config 实现分布式配置中心
Spring Cloud Config 实现分布式配置中心 一.分布式配置中心 分布式系统中,往往拥有大量的服务应用,而每个应用程序都需要有对应的配置文件来协助完成服务环境初始化.运行.因此生产了大量 ...
- 小程序模板template使用介绍
template(模板):是可以在wxml中引用的代码,就是在wxml中引用公用的wxml类型的代码,它的作用类似于组件,因此这里简单的说明下template与Component (组件)的区别. t ...