你真的懂使用Runtime进行swizzle的最佳写法?

简介: 前言runtime 的黑魔法很多人都一定听过,或者已经在使用了。但是,怎么swizzle方法才是最好呢?一般写法Method originalMethod = class_getInstanceMethod(aClass, originalSel...

前言

runtime 的黑魔法很多人都一定听过,或者已经在使用了。但是,怎么swizzle方法才是最好呢?

一般写法

Method originalMethod = class_getInstanceMethod(aClass, originalSel);
    Method swizzleMethod = class_getInstanceMethod(aClass, swizzleSel);
    method_exchangeImplementations(originalMethod, swizzleMethod);

或者是下面这种方式,swizzle第二种写法:

   Method originalMethod = class_getInstanceMethod(aClass, originalSel);
    Method swizzleMethod = class_getInstanceMethod(aClass, swizzleSel);
    BOOL didAddMethod = class_addMethod(aClass, originalSel, method_getImplementation(swizzleMethod), method_getTypeEncoding(swizzleMethod));
    if (didAddMethod) {
        class_replaceMethod(aClass, swizzleSel, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    }else{
        method_exchangeImplementations(originalMethod, swizzleMethod);
    }

更好写法

其它,这样写,一般不会有问题,但是在一些情况下,比如这个hook的类没有实现你要swizzle的方法,这时是没有swizzle成功的,然后你自己写的 swizzle 里又自己调用自己,就无限循环。

    Method originalInsMethod = class_getInstanceMethod(class, originalSelector);
    // 处理为实例方法
    if (originalInsMethod)
    {
        method_exchangeImplementations(originalInsMethod, swizzledMethod);
    }else{
        // 处理为类方法
        Method originalClassMethod = class_getClassMethod(class, originalSelector);
        if (originalClassMethod)
        {
            method_exchangeImplementations(originalClassMethod, swizzledMethod);
        }else{
            // 如果hook的类没有实现这个方法,则先添加方法,然后设置方法的IMP为一个空block。否则直接class_replaceMethod,则方法实则没有交接
            class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
            method_setImplementation(swizzledMethod, imp_implementationWithBlock(^(id self, SEL _cmd){}));
        }
    }

总结

至于这个为什么会更好? 有时间在慢慢说啦~

参考


注:本文首发于 iHTCboy's blog,如若转载,请注明来源。

目录
相关文章
|
并行计算 Ubuntu Linux
Ubuntu学习笔记(五):18.04安装多版本CUDA
这篇博客文章介绍了在Ubuntu 18.04系统上如何安装和切换不同版本的CUDA,以及如何安装不同版本的cuDNN。
1141 2
|
10月前
|
开发工具 图形学 Android开发
《Unity游戏多平台上架零驳回:应用商店适配核心技巧与避坑指南》
本文聚焦Unity游戏多平台上架的核心适配技巧与避坑要点,深入拆解主流应用商店的审核逻辑与技术要求。文章从平台规则差异、Unity技术适配、合规性把控、包体构建细节、审核驳回应对等维度,结合实战经验剖析上架关键环节:强调需穿透商店规则表象,适配不同平台的生态定位与硬件特性,解决引擎与设备的兼容性问题;重点关注隐私政策、支付合规、内容安全等合规红线,同时把控包体格式、签名、渠道标识等流程细节。针对审核驳回,提供精准排查、根源整改与专业申诉的实操思路,助力开发者避开隐形陷阱,实现多平台零驳回顺畅上架,为Unity游戏上架提供兼具深度与实用性的技术指引。
455 10
|
人工智能 数据可视化 测试技术
Coze平台指南(3):核心功能-创建智能体与设计角色
Coze 智能体是由大语言模型驱动,通过提示词设定角色,并借助知识库、插件和工作流扩展能力,以执行特定任务的AI助手。对测试工程师而言,精心设计的智能体可显著提升测试效率与质量,关键是要准确理解测试需求,并将其转化为智能体的角色设定和功能配置。建议进一步学习知识库与工作流,以深化应用。
|
弹性计算 开发工具 Android开发
阿里云APP备案流程图以及备案所需材料整理,跟着教程一步步操作
阿里云APP备案流程分为六步,确保应用合法上架。首先登录阿里云账号填写APP信息,提交后等待阿里云初审。初审通过后进行工信部短信核验,随后由管局审核。审核通过后,APP即可获得备案号并正式上架分发平台。整个过程需仔细填写主办者及APP详细信息,确保所有资料准确无误。阿小云详细分享了这一流程,帮助开发者顺利完成备案。
|
算法
动态规划算法学习三:0-1背包问题
这篇文章是关于0-1背包问题的动态规划算法详解,包括问题描述、解决步骤、最优子结构性质、状态表示和递推方程、算法设计与分析、计算最优值、算法实现以及对算法缺点的思考。
1009 2
动态规划算法学习三:0-1背包问题
|
JavaScript 前端开发
多种模块格式,包括 ES, CommonJS, UMD, AMD, SystemJS 和 IIFE的区别点分别是什么?
【10月更文挑战第20天】在实际应用中,选择合适的模块格式需要根据项目的需求、目标环境以及开发团队的习惯等因素来综合考虑。不同的模块格式都有其自身的优势和适用场景,合理选择可以提高代码的组织性、可维护性和性能。
741 8
|
机器学习/深度学习 人工智能 算法
《探索人工智能产业的可持续发展模式与策略》
在科技浪潮中,人工智能产业正成为经济增长和社会进步的关键力量。要实现其可持续发展,需从技术创新、产业协同、人才培养、数据管理等多方面入手。技术创新驱动性能提升,如深度学习突破图像和语音识别;产业协同推动智能制造、智能医疗等领域升级;高校与企业共同培养专业人才;数据管理和政策支持保障产业发展;国际合作与环保理念助力绿色AI技术发展。通过综合策略,推动人工智能健康、可持续发展。
348 8
|
算法 Java 大数据
【经典算法】LeetCode 283. 移动零(Java/C/Python3/Go实现含注释说明,Easy)
【经典算法】LeetCode 283. 移动零(Java/C/Python3/Go实现含注释说明,Easy)
500 0
|
API iOS开发
iOS底层原理:Method Swizzling原理和注意事项(二)
Method Swizzling的含义是方法交换,其核心内容是使用runtime api在运行时将一个方法的实现替换成另一个方法的实现。我们利用它可以替换系统或者我们自定义类的方法实现,进而达到我们的特殊目的,这就是我们常说的iOS黑魔法。
iOS底层原理:Method Swizzling原理和注意事项(二)
|
Java Android开发 C语言
【Android 系统开发】Android JNI 之 JNIEnv 解析(二)
【Android 系统开发】Android JNI 之 JNIEnv 解析(二)
429 0

热门文章

最新文章