runtime交换方法的正确姿势

2023-11-16

runtime交换方法的正确姿势

说到Objective-C大家就会想到黑魔法runtime,(不知道runtime是什么的看这里,runtime是开源的,源码在这里),本文主要讲解如何利用runtime正确的交换方法,将会提到两种方式去交换,以及我们在什么情况下改怎么去用。

我们知道OC的方法到了runtime就被体现成结构体

struct objc_method {
    SEL method_name                                          OBJC2_UNAVAILABLE;
    char *method_types                                       OBJC2_UNAVAILABLE;
    IMP method_imp                                           OBJC2_UNAVAILABLE;
}

要交换方法的话,无非也就是下面两个方法:

OBJC_EXPORT IMP method_setImplementation(Method m, IMP imp) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);
OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2) 
    OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);

我们通常同的估计也就是第二种方法吧,下面我们来看看用第二种方法存在什么样的问题,我们假设有这么两个方法:

Method m1 { 

      SEL method_name = @selector(originalMethodName)
      char *method_types = “v@:“ //returns void, params id(self),selector(_cmd)
      IMP method_imp = 0x000FFFF (MyBundle`[MyClass originalMethodName])
 }

Method m2 { 

       SEL method_name = @selector(swizzle_originalMethodName)
       char *method_types = “v@:”
       IMP method_imp = 0x1234AABA (MyBundle`[MyClass swizzle_originalMethodName])
 }

我们方法实现如下,在交换的方法里面调用原来的方法:

   - (void) originalMethodName //m1
     {
     }
     - (void) swizzle_originalMethodName //m2
     {
            [self swizzle_originalMethodName];//call original method
     }

那么这两个方法看起来就是这样的:

Method m1 { 

     SEL method_name = @selector(originalMethodName)
     char *method_types = “v@:“ //returns void, params id(self),selector(_cmd)
     IMP method_imp = 0x1234AABA (MyBundle`[MyClass swizzle_originalMethodName])
 }

Method m2 {

     SEL method_name = @selector(swizzle_originalMethodName)
     char *method_types = “v@:”
     IMP method_imp = 0x000FFFF (MyBundle`[MyClass originalMethodName])
 }

那么问题就来了,因为这样导致_cmd改变了,要是原来的方法根据_cmd做了操作的话(原方法实现一般都是看不到的),这时候就会出事了:

- (void) originalMethodName //m1
 {
          assert([NSStringFromSelector(_cmd) isEqualToString:@“originalMethodNamed”]);
 }

那么我们在看看OBJC_EXPORT IMP method_setImplementation(Method m, IMP imp)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);这个方法来交换方法,该方法调用之后会返回原方法的实现,知道上面的问题之后,我们最好的交换方式就是用一个C语言函数实现去替换原方法实现,C函数大概长这样的:

void __Swizzle_OriginalMethodName(id self, SEL _cmd)
 {
//调用原方法
originalImp(self,_cmd);
//code
 }

那么我们下面的代码可能长这样:

IMP swizzleImp = (IMP)__Swizzle_OriginalMethodName;
IMP originalImp = method_setImplementation(method,swizzleImp);

拿这两个方法来说,主要就是防止人家的代码里面根据selector参数去做了操作而出现问题,这种情况多出现在你的代码用作三方等,要是自己项目的话,还是随便写的,不过说回来,要是苹果的方法里面这样用了,那么我们就不能用OBJC_EXPORT void method_exchangeImplementations(Method m1, Method m2)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0);交换哦


还是那句话,如您发现任何错误,欢迎留言指正~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

runtime交换方法的正确姿势 的相关文章

  • 如何消除禁用的 UIButton 的灰色外观

    我有一个 UIButton 我希望它处于禁用状态时与处于正常状态时看起来完全相同 现在它看起来有点灰色 不要使用enabled属性或setEnabled NO方法 而是使用 myButton setUserInteractionEnable
  • 删除 UINavigationBar 下的 1px 边框 - 不起作用

    IBOutlet var navBar UINavigationBar self navBar setBackgroundImage UIImage forBarMetrics UIBarMetrics Default self navBa
  • 如何在 xcode 中使用相同的 nib 文件创建多个窗口

    我有一个使用表格视图作为界面的 iPhone 应用程序 每次用户点击其中一个表格单元格时 我想向用户显示另一个窗口 然而 我推入导航控制器的窗口的用户界面非常相似 因此 我决定制作一个 通用 nib 文件 以便在该通用 nib 文件的文件所
  • Objective-C 原始数之间的差异

    What is the difference between objective c C primitive numbers I know what they are and how to use them somewhat but I m
  • 如何将 NSString 值 @"3.45" 转换为浮点数?

    如何将 NSString 值 3 45 转换为浮点数 3 45 float fCost NSDecimalNumber decimalNumberWithString 3 45 floatValue NSString val 3 45 fl
  • 如何在 iOS 上捕获的视频中添加水印[重复]

    这个问题在这里已经有答案了 我想知道是否有人可以告诉我如何实现这一目标 如果一直在考虑几个解决方案 从捕获的视频创建单独的图像 然后将它们合并到每个图像中 然后创建一个新的 AVAsset 听起来有点复杂 您不觉得吗 合并2个视频 一个是透
  • 简单的 iPhone 运动检测

    我需要检测陀螺仪 加速度计何时被激活一定量 基本上是检测设备何时移动 我对核心运动一无所知 也许有人可以指导我入门教程或其他东西 提前致谢 我认为你必须使用 Core Motion 好消息是 它对于您的问题域来说并不难使用 开始阅读事件处理
  • 如何使用 MPMusicPlayerController 播放音乐?

    任何人都可以建议我如何在我的应用程序中使用 MPMusicPlayerController 播放音乐 任何人的帮助将不胜感激 谢谢你 莫尼什 创建一个MPMediaPickerController这样你就可以从 iPod 中选择一些音乐 然
  • iOS设备和iPhone模拟器内存​​组织的差异

    我正在尝试使用 Xcode 4 3 3 和 iPhone 5 1 模拟器开发一个应用程序 当我在模拟器上运行这个应用程序时 我没有收到任何警告 并且它运行得很好 但是 当我尝试在 iOS 设备上执行此操作时 我收到一条警告消息 收到内存警告
  • 停止 ARC 在空闲时释放对象

    我在 Objective C 中遇到内存管理问题 我一直在阅读高级内存管理编程指南 https developer apple com library mac documentation Cocoa Conceptual MemoryMgm
  • 在 Cocoa Mac OSX 中设置 FirstResponder 时出现问题

    我正在开发一个小应用程序只是为了学习可可 并且我很难将 FirstResponder 设置为某些 NSTextFields 当视图打开时 我希望选择第一个 NSTextField clientNumber 因此我在 loadView 方法末
  • 将UIWebView显示的PDF保存到本地

    我有一个UIViewController与UIWebView显示一个 pdf 文件 具体取决于之前单击的行UITableView 现在我想添加一个按钮 供用户在本地保存此 pdf 文件以供离线使用 然后还有第二个UITableView它应该
  • 使用自动布局时 UIScrollview 的中心内容

    我在项目中使用自动布局 并且有一个滚动视图 其中有一个居中的按钮 我已经让滚动视图滚动 但不占据整个屏幕 我尝试按照此处的教程进行操作 https developer apple com library ios technotes tn21
  • 从哪里开始使用适用于 Retina 显示屏的 OpenGL 绘制程序

    我知道由于这里提到的错误 我无法将 GLPainter 示例从苹果适应到视网膜 在 Retina iPad 上显示全屏 CAEAGLLayer 时出现问题 https stackoverflow com questions 9757052
  • 如何在 UITextView 中禁用放大功能

    我想摆脱 UITextView 中的放大和文本选择 但我需要电话号码 链接和地址检测器 我在用 void addGestureRecognizer UIGestureRecognizer gestureRecognizer if gestu
  • 如何在基于视图的应用程序中添加导航控制器

    我想向基于视图的应用程序添加导航控制器 我们如何以编程方式和使用 xib 文件来完成此操作 如果您需要在 uiviewcontroller 中合并导航控制器 您需要按如下方式初始化它 UIViewController yourViewCon
  • “EXC_BAD_ACCESS”与“分段错误”。两者实际上相同吗?

    在我的前几个虚拟应用程序 用于学习时练习 中 我遇到了很多EXC BAD ACCESS 这以某种方式告诉我错误访问是 您正在触摸 访问一个不应该的对象 因为它尚未分配或释放 或者只是您无权访问它 查看此示例代码 该代码存在访问错误问题 因为
  • iOS - 在 UITabBar 上方获取所需的阴影

    我试图让我的标签栏阴影看起来像这张图片中看到的那样 这样做的最佳方法是什么 我正在使用 Objective C Thanks 您可以使用以下代码为任何 UI 对象提供阴影 tabBar layer shadowOffset CGSize w
  • 为什么我无法更改 UIBarButtonItem 的标题?

    我想改变UIBarButtonItem s title 但这段代码不起作用 void viewDidLoad self smay void smay AppDelegate apd AppDelegate UIApplication sha
  • 如何使用呼叫目录扩展来识别应用程序中的来电?

    我正在研究callKit框架 我发现通过使用呼叫目录扩展 我们可以识别来电电话号码 我的问题是如何在 iOS 应用程序中实现呼叫目录扩展来识别来电详细信息 我在 Objective C 工作 让一个数 919876xxxxx 使用此方法添加

随机推荐

  • .NET Core与.NET Framework、Mono之间的关系

    随着微软的 NET开源的推进 现在在 NET的实现上有了三个 NET Framework Mono和 NET Core 经常被问起Mono的稳定性怎么样 后续Mono的前景如何 要回答这个问题就需要搞清楚这三个 NET 实现之间的关系和将来
  • Ubuntu 22.04 配置静态IP

    1 桥接模式 NAT模式 参考博客 虚拟机上网设置 桥接模式 NAT模式 2 interfaces配置文件 interfaces 5 file used by ifup 8 and ifdown 8 auto lo iface lo ine
  • 论文中图片加方框 matlab代码

    转自 http blog csdn net majinlei121 article details 52334171 加方框函数 cpp view plain copy function I rgb DrawRectangle I Left
  • pymysql介绍

    一 数据库介绍 概念 一个存放数据的仓库 这个仓库按照一定的数据结构组织 存放 管理数据 分类 关系型数据库 mysql sql server oracle DB2等 非关系型数据库 redis等 python操作数据库的方式 pymysq
  • 传统制造型企业如何实现数字化转型?

    传统制造企业可以通过采用技术和数据驱动的方法来实现数字化转型 以改善运营 提高效率并在快速发展的行业中保持竞争力 以下是他们可以遵循的步骤和策略 1 评估和战略制定 评估当前状态 首先评估制造流程 技术基础设施和数据管理系统的当前状态 确定
  • XSS攻击绕过过滤方法大全(转)

    XSS攻击绕过过滤方法大全 约100种 文章目录 XSS攻击绕过过滤方法大全 约100种 1 XSS定位器 2 XSS定位器 短 3 无过滤绕过 4 利用多语言进行过滤绕过 5 通过JavaScript命令实现的图片XSS 6 无分号无引号
  • windows用 tree命令查看目录文件夹结构

    windows用 tree命令查看目录文件夹结构 查看帮助 tree help tree dirsfirst filelimit 6 h t dirsfirst 目录优先展示 filelimit 6 文件夹下超过6个文件的将不展开 s 以字
  • 启动mysql服务的时候一直报ERROR! The server quit without updating PID file

    问题背景 最近在电脑的vmware上安装了个CentOS 7系统 并在系统中装了mysql 8 0 11 可是启动服务的时候一直报错 如下 root localhost etc service mysql start Starting My
  • CloudCompare二次开发(1)——获取指定高程的所有点

    目录 一 源码编译 二 制作流程 三 结果展示 本文由CSDN点云侠原创 原文链接 爬虫网站自重 一 源码编译 1 WIN10系统下VS2019编译CloudCompare2 12 4 二 制作流程 1 找到源码中的插件例子 主要支持三种插
  • 类什么时候被加载 java

    创建对象实例时 new 创建子类对象实例 父类也被加载 使用类的静态成员时 静态属性 静态方法
  • 软件工程—软件结构图笔记详谈

    一 定义 结构图 Structure Chart 简称SC图 是精确表达软件结构的图形表示方法 它以特定的符号表示模块 模块间的调用关系和模块间信息的传递 二 主要构成 模块 Module 用矩形框表示 框中写有模块的名字 说明模块的功能
  • 服务器ie浏览器总是未响应,win7电脑IE浏览器总是未响应怎么办 IE浏览器无响应原因解决方法...

    win7电脑IE浏览器总是未响应怎么办 IE浏览器无响应原因解决方法 2016 12 05 已有人学习 编辑 chenwei 来源 电脑技术吧整理 win7电脑IE浏览器总是未响应怎么办 IE浏览器无响应原因解决方法 我们在使用电脑的时候
  • Linux mysql启动失败 Job for mysqld.service failed because the control process exited with error code.

    一 查询mysql无法启动问题 service mysql start 启动mysql 报错 Job for mysqld service failed because the control process exited with err
  • outlook邮箱邮件内容乱码_outlook邮件乱码怎么转换

    造成邮件乱码的原因很多 但归纳起来不外乎有三种情况 一是操作系统和使用的软件设置不同导致的 二是发送邮件时发送程序采用不同的编码标准 如UU MIME BINHEX等 而你所用的操作系统程序没有能力将其解码 收到的邮件像 天书 一般 三是邮
  • 《Graph Neural Networks Foundations,Frontiers and Applications》第一部分第一章第1.2.2节翻译和解读

    书名 Graph Neural Networks Foundations Frontiers and Applications 图神经网络的基础 前沿和应用 出版社 Springer Berlin Heidelberg 作者 Lingfei
  • chatgpt赋能python:Python中如何写π

    Python中如何写 在Python中 写 Pi 即圆周率 可能是一个小小的挑战 但是 这个问题的答案相对比较简单 在本文中 我们将介绍如何在Python中计算 以及如何使用Python的数学库 math库 介绍 是一个十分重要的数学常数
  • 决策树与R语言(RPART)

    关于决策树理论方面的介绍 李航的 统计机器学习 第五章有很好的讲解 传统的ID3和C4 5一般用于分类问题 其中ID3使用信息增益进行特征选择 即递归的选择分类能力最强的特征对数据进行分割 C4 5唯一不同的是使用信息增益比进行特征选择 特
  • 自动寻路算法C语言,C语言实现A*算法

    CopyRight c HYTC Ltd All rights reserved Filename main c Creator GaoLei Version 0 0 Date 2011 06 15 QQ 38929568 Descript
  • 微信小程序中使用svga动画

    参考资料 https github com svga SVGAPlayer Web tree mphttps github com svga SVGAPlayer Web tree mp 也可以参考 我主要参考的上面的 https gith
  • runtime交换方法的正确姿势

    runtime交换方法的正确姿势 说到Objective C大家就会想到黑魔法runtime 不知道runtime是什么的看这里 runtime是开源的 源码在这里 本文主要讲解如何利用runtime正确的交换方法 将会提到两种方式去交换