手把手教你开发 JSDebugger 插件:从 JD_REGISTER_PLUGIN 宏到全局 JS 函数

📅 2026/8/18 14:09:55
手把手教你开发 JSDebugger 插件:从 JD_REGISTER_PLUGIN 宏到全局 JS 函数
手把手教你开发 JSDebugger 插件从 JD_REGISTER_PLUGIN 宏到全局 JS 函数【免费下载链接】JSDebuggerJavaScript-Based Debugger For Inspecting Running State Of Your Application项目地址: https://gitcode.com/gh_mirrors/js/JSDebuggerJSDebugger 是一款基于 JavaScript 的 iOS 应用运行时调试工具它最大的亮点是不需要手动定义任何 JSExport就能在 JavaScript 里直接调用任意 Objective-C 方法随时查看并修改 App 的运行状态。而让 JSDebugger 如此灵活的秘密武器正是它的插件机制。本文将以新手友好的方式带你完整走一遍 JSDebugger 插件开发流程——从认识 JD_REGISTER_PLUGIN 宏到让自定义函数出现在 JS 全局环境中。什么是 JSDebugger 插件机制JSDebugger 把扩展调试能力这件事完全交给了插件。官方内置了两个非常实用的插件choose()遍历堆内存找出指定类在运行时的所有实例introspect()检查某个对象的所有属性信息这两个函数在 JS 里用起来就像普通全局函数一样自然var vc choose(ViewController)[0]; // 找到所有 ViewController 实例 var info introspect(vc); // 查看它的全部属性它们不是写死在引擎里的而是通过一套统一的插件机制注册进去的。你完全可以照着它们的样子写出属于自己的插件。插件机制的三个关键角色 JSDebugger 插件机制由三部分构成角色职责源码位置JDFunctionPlugin 协议规定插件必须实现的方法Source/Core/Plugin/JDFunctionPlugin.hJDFunctionPluginManager收集并注册所有插件Source/Core/Plugin/JDFunctionPlugin.mJD_REGISTER_PLUGIN 宏一行代码完成声明 注册同上JDFunctionPlugin 协议插件的身份证 协议只要求实现两个方法key这个插件在 JS 中叫什么名字比如choosefunction这个插件对应的 C 回调函数指针JDFunctionPluginManager插件的大管家 ‍它是一个单例内部维护一个插件数组。addPlugin:负责收集插件registerPluginsIntoContext:负责把收集到的插件全部写入 JS 全局对象本质就是用 JavaScriptCore 的JSObjectMakeFunctionWithCallback为每个插件创建一个全局函数。引擎启动时Source/Core/JDEngine.m的start方法会自动调用它所以你完全不需要手动干预。JD_REGISTER_PLUGIN 宏三行代码解决注册 ⚡宏的完整定义是理解插件机制的核心建议收藏#define JD_REGISTER_PLUGIN(IMP, NAME) \ FOUNDATION_EXTERN void JDRegisterPlugin(Class pluginClass); \ (void)load {JDRegisterPlugin(self);} \ - (NSString *)key {return NAME;} \ - (JSObjectCallAsFunctionCallback)function {return IMP;}拆开看它其实帮我们自动完成了三件事声明注册函数JDRegisterPlugin在load时机自动注册类一被加载就立刻把自己交给插件管理器无需手动调用自动实现协议方法key返回宏里的 NAMEfunction返回宏里的 IMP 函数指针也就是说你只需要写一行JD_REGISTER_PLUGIN插件就自动被收编进系统了就是这么简单。认识官方内置插件choose 与 introspect choose的完整实现约 150 行C 与 Objective-C 混合核心是通过遍历 malloc 内存区域、比对 isa 指针来定位目标类的实例。但它的插件声明部分只有一行JD_REGISTER_PLUGIN(choose, choose);introspect更简洁本质是把对象的所有属性转成数组返回JD_REGISTER_PLUGIN(introspect, introspect);参考源码JDChoose.mm、JDIntrospect.mm。手把手开发第一个 JSDebugger 插件 ️现在轮到你了我们来做一个简单但完整的示例给 JS 增加一个version()函数返回当前 App 的版本号。第一步创建插件类并遵守协议新建一个 Objective-C 类声明遵守JDFunctionPlugin协议并引入头文件。第二步写 C 回调函数实现一个JSObjectCallAsFunctionCallback类型的 C 函数。当 JS 里调用version()时这个函数就会被触发并返回一个 JSValueRefstatic JSValueRef version(JSContextRef ctx, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef *exception) { // 返回一个 JS 字符串 1.0.0 return JSValueMakeString(ctx, JSStringCreateWithUTF8CString(1.0.0)); }第三步用宏注册在implementation里写一行即可JD_REGISTER_PLUGIN(version, version);第四步启动引擎并在 JS 中调用 App 启动时调用[[JDEngine engine] start];之后在 JS 里就能直接使用var v version(); console.log(v); // 输出 1.0.0四个实用小贴士 注册时机是load插件类只要被链接进工程就会自动注册无需手动初始化任何东西。IMP 参数必须是函数指针注意宏里传的是version取地址不是方法实现。注册后的函数不可删除插件写入全局对象时带有kJSPropertyAttributeDontDelete属性在 JS 里delete是无效的。先用官方 demo 验证可以运行JSDebuggerDemo/demo.js里面已经演示了choose()等函数的完整用法是很好的入门参考。如何快速跑起来体验插件开发 最简单的方式是用 CocoaPods 集成参考JSDebugger.podspec与JSDebuggerDemo/Podfile也可以直接 clone 官方 Demo 工程git clone https://gitcode.com/gh_mirrors/js/JSDebugger打开 JSDebuggerDemo 工程后配合Playground 热加载功能JDLocalFileObserver监听文件变化保存即自动重新执行 JS改一行脚本马上看到效果插件开发调试的体验会非常丝滑。✨结语 从JD_REGISTER_PLUGIN宏到全局 JS 函数JSDebugger 的插件机制把给调试器添加新能力这件事压缩到了极致一个 C 函数 一行宏。掌握了它你就能按需定制自己的调试工具箱——无论是批量查找对象、动态修改 UI还是注入自定义调试命令都能信手拈来。快去动手试试吧【免费下载链接】JSDebuggerJavaScript-Based Debugger For Inspecting Running State Of Your Application项目地址: https://gitcode.com/gh_mirrors/js/JSDebugger创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考