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 : ...
随机推荐
- Cesium专栏-百度地图加载(附源码下载)
Cesium 是一款面向三维地球和地图的,世界级的JavaScript开源产品.它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以 ...
- 4.Android-adt安卓打包过程、adb指令学习
本章学习adt安卓打包过程.adb指令学习.并通过adb将打包的APK发给设备 1.打包 在eclipse中已经帮我们实现打包了. 具体打包流程如下: 最终一个APK包含了如下: classes.de ...
- react-native run-ios “Could not find iPhone X simulator”
问题 这个问题发生在旧的RN版本(0.57,0.58(<0.58.4),-)和Xcode 10.3中,其中可用模拟器的名称得到了一些调整 在文件node_modules/@react nativ ...
- 因为new Date(),我给IE跪了
处理日期格式是日常工作中的常事,我们经常会对日期字符串和日期对象之间进行转换.今天在IE浏览器就踩了这么一个日期转换的坑. new Date()的坑 后端返回的日期字符串格式为:yyyy-MM-dd ...
- 一目了然卷积神经网络 - An Intuitive Explanation of Convolutional Neural Networks
An Intuitive Explanation of Convolutional Neural Networks 原文地址:https://ujjwalkarn.me/2016/08/11/intu ...
- Maven pom.xml文件深度学习
本文介绍Maven项目构建中,pom.xml文件的生成规则和常用节点的使用方法.pom.xml官方网址:http://maven.apache.org/pom.html pom简介 pom作为项目对象 ...
- jQuery实现下拉框默认选中
<form class="form-inline" method="post" action="/score_result/"> ...
- 我应该怎么学习SAP?
越来越多的人关注本公众号,在后台留言问我怎么进入SAP行业,应该怎么学习SAP,大部分都是外行想入行SAP的朋友.作为过来人,这些问题我也曾经问过别人,也走过不少弯路.但现在轮到别人问我了,为了让初学 ...
- 46.QT-自带库QSerialPort串口使用
之前一章学习的是第三方库使用: 34.QT-qextserialport第三方库制作串口助手(并动态检测在线串口,附带源码) 本章来学习自带serial库 1.QSerialPortInfo QLis ...
- canvas在vue中的应用
使用cavas可以绘制各种图表.生成二维码.制作H5小游戏. 生命周期 canvas应该在mounted的生命周期中初始化,在updated中是无效的. export default { mounte ...