JSDebugger 源码架构梳理:一张图看懂 JDEngine、FFI、Plugin 等 10 大核心模块

发布时间:2026/10/5 23:01:05

JSDebugger 源码架构梳理:一张图看懂 JDEngine、FFI、Plugin 等 10 大核心模块 JSDebugger 源码架构梳理一张图看懂 JDEngine、FFI、Plugin 等 10 大核心模块【免费下载链接】JSDebuggerJavaScript-Based Debugger For Inspecting Running State Of Your Application项目地址: https://gitcode.com/gh_mirrors/js/JSDebuggerJSDebugger 是一个基于 JavaScript 的 iOS 应用调试工具它最酷的地方在于你可以用 JS 脚本直接查看和操作正在运行的 Objective-C 对象。想搞懂它的源码架构只需抓住 JDEngine、FFI、Plugin 三大主线再配合 10 大核心模块逐个击破整个设计脉络就会非常清晰。本文用「一张架构图 模块拆解」的方式带你快速读懂这份 iOS 调试器源码。JSDebugger 是什么为什么值得读源码简单说JSDebugger 在 App 内部嵌入了一个 JavaScriptCore 运行时让 JS 可以直接访问 Objective-C 的类、对象、方法、属性。调试时你不用断点、不用 LLDB写几行 JS 就能打印任意对象的属性、调用任意方法。对于想学习iOS 与 JavaScript 互调、Objective-C 运行时Runtime应用、FFI 函数调用的开发者来说这份源码架构堪称教科书级范例。一张图看懂整体架构整个工程分为三层入口层 → 核心运行时层 → 工具/文件监听层核心逻辑几乎全部集中在Source/Core目录下。┌─────────────────────────────────────────────────────┐ │ 入口层 JDEngine / JSDebugger.h │ │ 单例启动、创建 JS 全局上下文、注册插件 │ ├─────────────────────────────────────────────────────┤ │ 核心运行时层Source/Core │ │ ├─ JSDefinition JDClass4JS / JDInstance4JS │ │ │ JDMethod4JS / JDPointer4JS │ │ ├─ Runtime JDMethodBridge / JDEncoding │ │ │ JDJSTypeToOCType / JDOCTypeToJSType│ │ │ JDPropertyCache / JDStruct │ │ ├─ FFI JDFFIContext真正的函数调用 │ │ └─ Plugin JDFunctionPlugin │ │ Plugin/JDChoose / Plugin/JDIntrospect│ ├─────────────────────────────────────────────────────┤ │ 工具/监听层 JDNSStringFromJSString / JDFormatJSFunction│ │ NSObjectJDRuntimeIntrospection │ │ JDLog │ ├─────────────────────────────────────────────────────┤ │ 文件热更新层 FileWatcher/JDLocalFileObserver │ │ FileWatcher/JDLocalFilePresenter │ └─────────────────────────────────────────────────────┘下面按这张图逐一拆解 10 大核心模块。一、JDEngine一切从「入口」开始JDEngine 是整个调试器的单例入口源码在 JDEngine.h 与 JDEngine.m。它的职责非常聚焦创建 JS 全局上下文初始化JSGlobalContextRef并给全局对象挂上getProperty回调。这样你在 JS 里写UIView它就能自动通过NSClassFromString找到对应的 OC 类并包装成 JS 对象。注册插件start方法调用JDFunctionPluginManager把全部插件注册进 JS 上下文。执行脚本提供evaluateScript:和evaluateScriptAtPath:两个 API执行前还会用JSCheckScriptSyntax做语法检查。入口层最大的设计亮点是全局对象被改造成一个「类查找器」代码量不多却是整个 JS 世界的门户。二、JSDefinition 四件套把 OC 对象「翻译」成 JS 对象这一组模块定义了四种 JS 类是 JS 与 OC 互转的基石全部位于 Source/Core/Runtime/JSDefinition模块文件职责JDClass4JSJDClass4JS.m把 OC 类包装成 JS 对象读取属性时通过 Runtime 查找类方法JDInstance4JSJDInstance4JS.h把 OC 实例包装成 JS 对象getProperty时走实例方法JDMethod4JSJDMethod4JS.h把 OC 方法包装成 JS 函数触发调用时进入桥接层JDPointer4JSJDPointer4JS.h封装原始指针让 JS 能持有 C 指针JDClass4JS 的实现很有代表性当 JS 访问MyClass.someMethod时它用NSSelectorFromStringJDFormatJSFunction把 JS 方法名转成 OC selector再通过class_getClassMethod找到方法返回一个 JDMethod4JS 包装对象。三、JDMethodBridgeJS 调用 OC 方法的中转站JDMethodBridge.h 是方法调用的「参数说明书」。它记录了方法签名NSMethodSignature用来解析返回值和参数类型selector 与 IMP 函数指针目标实例instance。当 JS 侧调用一个方法时桥接层会先解析每个参数的类型编码JDEncoding把 JS 值转换成对应的 OC 类型再用objc_msgSend或 FFI 完成真正的调用。四、JDFFIContext底层函数调用的发动机FFI这是整个项目技术含量最高的部分。目录 Source/Core/FFI 下内置了从ffi.h到ffi_arm64.h等多套 libffi 头文件及静态库 libffi.a。JDFFIContext.h 只暴露一个核心函数JDCallFunction(ctx, methodBridge, argumentCount, arguments);它的作用是在运行时动态构造函数调用根据JDMethodBridge里的签名信息用 libffi 把 JS 参数逐个转换成正确的 C 类型并压栈调用。这也是为什么 JSDebugger 能调用任意 OC 方法——它不依赖编译期绑定完全靠运行时描述。五、JDFunctionPlugin可插拔的 JS 能力扩展插件系统让调试器可以零侵入地扩展 JS 全局函数。核心代码在 JDFunctionPlugin.h 与 JDFunctionPlugin.m。用法极其优雅一个宏就能注册插件JD_REGISTER_PLUGIN(IMP, NAME)JDRegisterPlugin在load时自动把插件实例加入单例管理器registerPluginsIntoContext:把插件的function回调以key为名挂到 JS 全局对象上。项目内置了两个典型插件JDChoose.mm提供一个choose()全局函数用来按条件查找 OC 对象JDIntrospect.mm提供一个introspect()函数用来查看对象的类层级与结构。六、JDEncoding 与双向类型转换JS 与 OC 的「翻译官」JS 和 OC 的类型体系完全不同必须有一套双向转换规则JDEncoding.h解析 OC 类型编码如、i、{CGRect...}JDJSTypeToOCType.m把 JS 值number、string、object转成 OC 对象/C 结构体JDOCTypeToJSType.m把 OC 返回值转回 JS 值。加上工具类 JDNSStringFromJSString.m 负责 JSString 与 NSString 互转整条类型链路就闭环了。七、JDPropertyCache属性访问的高性能缓存JDPropertyCache.m 负责缓存类的属性信息。每次 JS 读取 OC 属性时如果都重新遍历class_copyPropertyList会非常慢缓存层把属性名与 getter/setter 的映射存起来第二次访问直接命中大幅提升调试体验。配套的 JDProperty.m 则封装单个属性的读取与写入逻辑。八、NSObjectJDRuntimeIntrospection一行代码打印对象全貌JDIntrospect 是一个 Objective-C 分类给所有 NSObject 增加了jd_logAllProperties方法可以一次性输出对象的所有属性值。这是新手理解 Runtime 自省Introspection的最佳入门代码。九、JDLocalFileObserverJS 脚本热更新目录 Source/FileWatcher 实现了文件监听JDLocalFileObserver.h监听指定 JS 文件文件变化时触发changeBlockJDLocalFilePresenter 配合完成文件的读取与分发。配合JDEngine的evaluateScriptAtPath:你可以在开发时改完 JS 文件立即生效不用重新编译 App这是它作为调试器最爽的体验之一。十、JDStruct 与 JDLog最后两块拼图JDStruct.m在start时注册常用的 C 结构体如 CGRect到 JS 环境让 JS 也能创建和解析结构体JDLog.mm统一日志输出所有调试信息都从这里打印。一次 JS 调用的完整旅程把上面模块串起来当你在 JS 里写[[UIApplication sharedApplication] delegate]时源码架构是这样运转的JDEngine的全局对象回调按名字UIApplication找到 OC 类JDClass4JS把类包装成 JS 对象方法访问返回JDMethod4JS真正调用时进入JDMethodBridge解析签名JDFFIContext用 libffi 动态完成 C 层函数调用返回值经JDOCTypeToJSType转回 JS 值交还给你。整个过程就是「类查找 → 对象包装 → 签名解析 → FFI 调用 → 类型回转」五个环节。总结给源码阅读者的三点建议从入口读起先读 JDEngine.m 的start和evaluateScript:建立全局观跟一条调用链用上面「一次 JS 调用的完整旅程」做主线从 JDClass4JS 一路追到 JDFFIContext对照 Demo 理解仓库自带 JSDebuggerDemo 工程和 demo.js 示例脚本边跑边读理解速度翻倍。想动手研究源码可以 clone 仓库https://gitcode.com/gh_mirrors/js/JSDebugger到本地配合 Xcode 打开 Demo 工程体验「JS 操控 OC」的魔力。掌握了这套源码架构你不仅能看懂 JSDebugger更能举一反三理解所有 JS 引擎嵌入式调试工具的设计思路。【免费下载链接】JSDebuggerJavaScript-Based Debugger For Inspecting Running State Of Your Application项目地址: https://gitcode.com/gh_mirrors/js/JSDebugger创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/6 5:43:38

全面战争传奇大不列颠王座Wemod修改测试全记录

前阵子我干了一件有点“自找麻烦”的事:把《全面战争传奇:大不列颠王座》从库存里翻出来,配合Wemod做了一轮完整的修改测试。标题里那句“全面战争大不列颠王座传奇wemod修改测试”,核心其实就是三件事——确认哪些修改项能生效、…

2026/10/6 5:43:38

Agent-Reach:本地AI智能体一键暴露为OpenAI兼容API的CLI工具

1. 项目概述:Agent-Reach 是什么,它解决的是哪类真实痛点?Agent-Reach 不是一个抽象概念或空泛口号,而是一个真实存在的、面向开发者与AI工程实践者的命令行工具(CLI),它的核心定位非常清晰&…

2026/10/6 5:43:38

Boost电路占空比实战指南:CCM/DCM模式切换与临界电感计算

1. 这不是教科书里的占空比,是焊过板子、调过波形、烧过MOSFET后才敢写的实战笔记“Boost电路占空比计算”这八个字,看起来像模电课本里一页翻过去就忘的公式推导。但如果你真在实验室里焊过一块升压板——输入12V想稳稳输出24V给电机供电,结…

2026/10/6 5:43:38

跨客户端AI记忆共享系统的自研实践:从mem0对比到混合检索落地

先交代背景。我一直在做 AI 辅助日常工作的落地,桌面端、Web 端、手机端、编辑器插件轮着用。用了半年多,最烦的一个问题就是:同一个 AI 服务,在这个客户端里聊过的上下文,换到另一个客户端就全断了。比如我在电脑上让…

2026/10/6 5:43:38

单文件AI编码代理实战:GUI操控与MCP协议全解析

1. 这个项目到底解决什么问题先说说我为什么会做这个东西。用过 Cursor、Copilot 这类编码工具的都知道,AI 补全代码已经不算新鲜事了,真正卡脖子的是“AI 只能改代码,不能替你操作电脑”。你在 IDE 里让它改个文件没问题,可一旦涉…

2026/10/6 5:38:37

VC6.0股票行情源码解析:MFC定时器与列表刷新实战

简介:这是一套基于VC6.0开发的股票软件源代码,聚焦股票列表实时行情刷新功能,实现每3秒刷新一次,并以中远海控为例演示脱机使用场景。数据接口对接腾讯股票实时行情数据,适合具备一定C与MFC基础、希望研究行情推送与界…

2026/10/5 6:32:56

Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化

1. 从“Jev”说起:为什么我要把Agent接进浏览器“Jev”这个词最近在圈子里出现的频率越来越高,很多人第一次听到会以为是某个新模型的名字,其实它更像是一种思路——把Jev模型的能力当作底座,通过Agent的方式去接管浏览器&#xf…

2026/10/6 4:01:51

多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系

1. 从"单兵作战"到"集群协同":多智能体编排到底在解决什么问题如果你最近在折腾 Agent 相关的东西,大概率会有一种感觉:单个 Agent 能做的事情,其实很快就摸到天花板了。你给它一个提示词,挂几个工…

2026/10/5 17:38:27

无源低通滤波器设计实战:从RC到LC,手把手教你避开那些坑

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

2026/10/6 0:03:23

MR25H40CDF+STM32F031C6工业级高可靠数据存储方案

1. 项目概述:为什么在工业现场非得用 MR25H40CDF 配 STM32F031C6 做数据存储?在工厂产线的 PLC 控制柜里、在风电变流器的散热片背面、在矿井监测终端的金属外壳下,你经常能看到一块指甲盖大小的黑色芯片——它既不是 Flash,也不是…

2026/10/6 0:03:23

MRAM+STM32工业断电数据保全实战指南

1. 项目概述:为什么在工业现场非得用 MR25H40CDF 配 STM32F031C6 做数据存储?在工厂产线的PLC柜里、在野外无人值守的环境监测终端里、在高速运转的包装机控制板上,你经常能看到一块指甲盖大小的黑色芯片,旁边贴着“MR25H40CDF”丝…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑