当前位置: 首页 > news >正文

iOS主要知识点梳理回顾-5-运行时方法交换

方法交换可以放在 +load+initialize 方法中,也可以自己根据时机来空,比如开启某个开关后才需要交换方法。如果是在+load中调用,交换工作会在类加载时(程序启动)自动调用;如果是在+initialize中调用,则会在该类初次发送消息的时候调用(如初始化、调用类方法等)。我们可以根据实际需要决定调用调用时机

实现交换

#import <objc/runtime.h>

@implementation UIViewController (Swizzling)

+ (void)load {
    // 获取原始的方法
    Method originalMethod = class_getInstanceMethod(self, @selector(viewWillAppear:));
    
    // 获取要交换的自定义实现方法
    Method swizzledMethod = class_getInstanceMethod(self, @selector(xxx_viewWillAppear:));
    
    // 交换方法
    BOOL didAddMethod = class_addMethod(self, @selector(viewWillAppear:), method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
    
    if (didAddMethod) {
        // 如果方法添加成功,说明原来类没有实现 viewWillAppear,直接使用交换后的方法
        class_replaceMethod(self, @selector(xxx_viewWillAppear:), method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    } else {
        // 如果原有的方法已经实现,则交换两个方法的实现
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

- (void)xxx_viewWillAppear:(BOOL)animated {
    // 在这里可以调用自己的实现
    [self xxx_viewWillAppear:animated]; // 注意:这里调用的是交换后的实现

    // 自定义代码,或者添加日志、调试等
    NSLog(@"viewWillAppear 被交换了!");
}

@end

关键点

  • class_getInstanceMethod:用来获取类的实例方法。
  • method_exchangeImplementations:用来交换两个方法的实现。
  • class_addMethod:如果目标方法不存在,可以添加一个新的方法。
  • method_getImplementationmethod_getTypeEncoding:分别获取方法的实现和类型编码。

注意事项

  • 递归调用:在 xxx_viewWillAppear: 方法内部,我们使用了 self xxx_viewWillAppear:animated; 来避免递归调用自身。因为方法已经交换,这行代码会触发原始的 viewWillAppear: 方法调用。
  • 调用顺序:交换方法的顺序是非常重要的。在我们的例子中,我们在自定义方法中先执行了交换后的实现 (xxx_viewWillAppear:),然后再执行原始的 viewWillAppear:。这样可以确保自定义的行为不会丢失。

实际应用

此类应用比较多的就是数据统计,比如统计页面浏览、元素点击,通过方法交换植入监控程序,大大提高开发效率。

http://www.dtcms.com/a/14314.html

相关文章:

  • Jmeter+Influxdb+Grafana平台监控性能测试过程
  • STM32F407通过FSMC扩展外部SRAM和NAND FLASH
  • Gitlab中如何进行仓库迁移
  • 游戏应用谷歌后台使用介绍
  • 设计模式Python版 命令模式(上)
  • conda 修复 libstdc++.so.6: version `GLIBCXX_3.4.30‘ not found 简便方法
  • 如何在Servlet容器中使用HttpServletResponse?
  • 【Mybatis】动态 SQL:代码与数据的灵动共舞,奏响数据库查询的华丽乐章
  • day9手机创意软件
  • 小程序canvas2d实现横版全屏和竖版逐字的签名组件(字帖式米字格签名组件)
  • Java面试题总结 - Java多线程篇(附答案)
  • Open Liberty使用指南及微服务开发示例(二)
  • DataBase【MySQL基础夯实使用说明(下)】
  • 在软件产品从开发到上线过程中,不同阶段可能出现哪些问题,导致软件最终出现线上bug
  • 网络安全之探险
  • Python Pandas(7):Pandas 数据清洗
  • Log4j定制JSON格式日志输出
  • 常用共轭先验分布
  • AWTK-WEB 快速入门(4) - JS Http 应用程序
  • Redis7——基础篇(一)
  • Jenkins 安装插件 二
  • MySQL - 索引 - 介绍
  • 如何下载Qt和运行第一个程序。
  • 【Elasticsearch】字符过滤器Character Filters
  • 51单片机之引脚图(详解)
  • postgresql源码学习(59)—— 磁盘管理器 SMGR
  • C#快速排序QuickSort将递归算法修改为堆栈Stack非递归方式
  • vue+springboot+webtrc+websocket实现双人音视频通话会议
  • Redisson介绍和入门使用
  • 二十六、使用docsify搭建文档管理平台