JRSwizzle新特性解析:withBlock如何优雅Hook方法?NSInvocation机制深度揭秘
JRSwizzle新特性解析withBlock如何优雅Hook方法NSInvocation机制深度揭秘【免费下载链接】jrswizzleone-stop-shop for all your method swizzling needs项目地址: https://gitcode.com/gh_mirrors/jr/jrswizzleJRSwizzle 是一款 Objective-C 方法交换Method Swizzling工具库其 v1.1.0 版本新增的withBlock 特性让开发者可以只用一个 Block 就优雅地 Hook 任意方法并借助 NSInvocation 机制灵活修改参数、调用原实现、读取返回值。本文将带你快速搞懂 withBlock 方法 Hook 的原理与用法。为什么要用 withBlock 来做方法 Hook传统的 objc 方法交换需要三步写一个影子方法、声明到分类里、再手动交换实现。而 JRSwizzle 经典的 jr_swizzleMethod:withMethod:error: 接口虽然只需一行调用但 Hook 逻辑仍然要提前写成独立方法不够灵活。v1.1.0 新增的 jr_swizzleMethod:withBlock:error: 和 jr_swizzleClassMethod:withBlock:error: 解决了这个问题Hook 逻辑直接写进 Block 里还能在 Hook 内部暂停原方法、改参数、拿返回值非常适合埋点、监控、A/B 测试等场景。快速上手3 步完成 withBlock 方法交换1️⃣ 安装 JRSwizzle 依赖项目自带 JRSwizzle.podspec用 CocoaPods 即可引入MIT 协议iOS 4.3 / OS X 10.6pod JRSwizzle也可以直接 clone 源码仓库git clone https://gitcode.com/gh_mirrors/jr/jrswizzle2️⃣ 写 Hook 代码完成方法交换以 HookinitWithCoder:为例完整示例见 JRSwizzle.h 的注释__block NSInvocation *invocation nil; invocation [MyView jr_swizzleMethod:selector(initWithCoder:) withBlock:^(id obj, NSCoder *coder) { NSLog(before %, obj); [invocation invokeWithTarget:obj]; // 这里才执行原实现 id ret nil; [invocation getReturnValue:ret]; // 拿到返回值 NSLog(after %, ret); return ret; } error:nil];注意两个关键点用__block修饰 invocation因为 Block 内部要引用这个还没赋值完的变量必须先调用[invocation invokeWithTarget:]类方法则直接[invocation invoke]才能执行原方法否则原逻辑会被跳过。3️⃣ Hook 类方法一行切换Hook 类方法时换成 jr_swizzleClassMethod:withBlock:error: 即可它会自动把 invocation 的 target 设为类本身Block 里直接[classInvocation invoke]就能调用原类方法。源码揭秘withBlock 方法交换的 4 个关键步骤核心实现只有 15 行左右位于 JRSwizzle.m拆解如下第 1 步Block 转函数指针IMP blockIMP imp_implementationWithBlock(block);运行库把 Block 包装成一个可直接调用的实现IMP。这样 Block 就能冒充一个 ObjC 方法。第 2 步动态注册唯一选择器NSString *blockSelectorString [NSString stringWithFormat:_jr_block_%_%p, ...]; SEL blockSel sel_registerName([...]);JRSwizzle 用_jr_block_原方法名_Block内存地址拼出一个临时选择器并注册到运行库保证多次 Hook 互不冲突——同一方法可以被 Hook 多次。第 3 步把 Block 挂载成类方法class_addMethod(self, blockSel, blockIMP, origSelMethodArgs);复用原方法的类型编码type encoding注册临时方法同时基于同一份类型信息构造好 NSMethodSignature生成返回给用户的NSInvocation对象。第 4 步复用经典 swizzling 完成交换[self jr_swizzleMethod:origSel withMethod:blockSel error:nil];最后调用项目里久经考验的 经典方法交换实现它先检查继承方法陷阱这正是 JRSwizzleTest/ 中 Scenario 7/8 测试覆盖的场景必要时用class_addMethod把继承方法提升到当前类再交换 IMP。NSInvocation 在这里的角色它就像一个可暂停、可改参、可读取返回值的方法调用遥控器。withBlock 接口把 invocation 返回给调用方Block 执行时就拥有了完整的调用控制权——这就是 深度 Hook 与普通 Hook 的本质区别。性能注意事项与实用建议要点说明⚠️ 性能NSInvocation 本身开销不小官方 README 也明确提示not the fastest of APIs高频调用的方法不建议用 withBlock可改用经典 withMethod 接口✅ 时机方法交换应尽早执行推荐load或initialize且每次只交换一次多次交换会叠加 Hook✅ 恢复再次用同一接口交换一次即可还原Block 版可传回原逻辑再交换或以原方法换回✅ 排查出错时通过error参数读取诊断信息JRSwizzle 的错误提示非常详细见 SetNSError 宏总结JRSwizzle 的 withBlock 特性把方法交换 参数拦截 返回值读取三件事压缩进一段 Block 代码底层通过imp_implementationWithBlock将 Block 变成方法实现动态注册临时选择器后复用经典 swizzling 完成交换再借NSInvocation把调用控制权交还给你。对于埋点、兼容性补丁、第三方库行为定制等场景它是目前最轻量的 objc 方法 Hook 方案之一。相关源码导航接口声明JRSwizzle.hBlock 版交换实现JRSwizzle.m经典交换与继承方法处理JRSwizzle.m测试用例JRSwizzleTest/JRSwizzleTest.m项目介绍与版本历史README.markdown【免费下载链接】jrswizzleone-stop-shop for all your method swizzling needs项目地址: https://gitcode.com/gh_mirrors/jr/jrswizzle创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Python爬虫爬取|地图POI采集实战:行政区检索、结果去重与合规边界

Python爬虫爬取|地图POI采集实战:行政区检索、结果去重与合规边界

第 029 篇 | 地理数据 | 高级

2026/10/4 7:44:15 阅读更多 →
Java学习五 面向对象高级5 内部类4-匿名内部类(重点)

Java学习五 面向对象高级5 内部类4-匿名内部类(重点)

1.例子:接口:测试类:总结:

2026/10/4 9:53:52 阅读更多 →
从IEEE Xplore数据库顶级检索频次看工学热门领域

从IEEE Xplore数据库顶级检索频次看工学热门领域

从IEEE Xplore数据库顶级检索频次看工学热门领域 此截图来自:IEEE Xplore 分析说明:工学的热门领域排序(降序) 数据科学图像处理机器学习深度学习天线人工智能(AI)云计算物联网(IoT)超大规模集成电路(VLSI)网络安全区块链声纳 其…

2026/10/3 7:33:09 阅读更多 →

最新新闻

Excel Wind插件与Python接口在债券数据批量处理中的协同实践

Excel Wind插件与Python接口在债券数据批量处理中的协同实践

开年以来好几拨做债券的朋友问我,平时用Excel的Wind插件取数写报告没什么问题,但要批量算组合持仓的久期、凸性,或者想把Wind行情推到自研的估值模型里跑一遍,Excel手工复制粘贴实在扛不住。这个需求本质上是两套工具链的问题&…

2026/10/4 11:12:46 阅读更多 →
OpenShell:基于zsh插件生态与fzf/zoxide的高效终端环境搭建

OpenShell:基于zsh插件生态与fzf/zoxide的高效终端环境搭建

做服务端开发和运维的朋友,应该都有过这样的经历:历史记录翻到手指发酸,同一个命令因为参数差一个字母敲了七八遍,项目目录越嵌越深、cd越敲越长。我就是被这些小事折磨到不行,才在前年开始系统整理自己的终端环境&…

2026/10/4 11:12:46 阅读更多 →
minicron 双语言架构深度剖析:Go 客户端 + Ruby 服务端如何高效监控 cron 任务

minicron 双语言架构深度剖析:Go 客户端 + Ruby 服务端如何高效监控 cron 任务

minicron 双语言架构深度剖析:Go 客户端 Ruby 服务端如何高效监控 cron 任务 【免费下载链接】minicron 🕰️ Monitor your cron jobs 项目地址: https://gitcode.com/gh_mirrors/mi/minicron 🕰️ minicron 是一款专为 cron 任务监控…

2026/10/4 11:12:46 阅读更多 →
Claude Code卡顿排查:Spinner状态解读与解决方案

Claude Code卡顿排查:Spinner状态解读与解决方案

说个我这两天的真实经历:在终端里跑 Claude Code,把一个接口的校验逻辑改到一半,命令刚发出去,屏幕就剩下一个小转圈在那一圈一圈地转。等了两分钟没动静,当时我心想——完了,这不是又卡死了。后来按了一次…

2026/10/4 11:12:45 阅读更多 →
Node.js 测试结构最佳实践:用 AAA 模式(Arrange-Act-Assert)组织可读性强的测试

Node.js 测试结构最佳实践:用 AAA 模式(Arrange-Act-Assert)组织可读性强的测试

文档教程后端 【免费下载链接】nodebestpractices ✅ The Node.js best practices list (July 2026) 项目地址: https://gitcode.com/GitHub_Trending/no/nodebestpractices 点击查看 免费下载 本文基于开源仓库 nodebestpractices(The Node.js best pr…

2026/10/4 11:12:45 阅读更多 →
黄仁勋2026GTC演讲全文:TaoToken统一Key看CUDA与GPU的AI新叙事

黄仁勋2026GTC演讲全文:TaoToken统一Key看CUDA与GPU的AI新叙事

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 11:11:45 阅读更多 →

日新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 1:00:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 10:36:31 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/3 9:42:36 阅读更多 →