工具简介
InjectionⅢ是作者John Holdsworth开源的一款iOS热重载工具,当APP在模拟器上编译运行后,使用它可以即时的执行项目中代码的改动,无需重新编译整个项目,从而极大的提高代码的调试效率。
InjectionⅢ大概的工作原理是:
- 在APP启动时,以加载NSBundle的形式在APP中运行一个Client端;
- InjectionⅢ作为Server端监视指定目录下文件的改动,当文件发生改动时将改动的文件重新编译为一个动态库;
- 动态库编译完成后,通过socket通信通知Client端,让APP去加载这个动态库(dlopen);
- 动态库加载完成后,再通过Runtime的class_replaceMethod将原来类中的方法都替换为动态库中新类的方法;
- 最后再调用文件中的类及其对象的
injected
方法,以便在其中调用修改后的代码; - 最终完成了对当前文件中代码改动的动态调试;
工具教程
1.安装
InjectionⅢ可以在Mac的应用商店中下载,也可以通过源码安装:clone或者下载源码,构建源码中的InjectionⅢ.xcodeproj工程即可。如果通过源码安装,卸载时删除构建源码时生成的xcode插件即可,终端命令:
1 | rm -rf ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins/InjectionPlugin.xcplugin |
2.使用
首先在InjectionⅢ中通过Open Project或Add Directory添加需要监视的文件目录,并勾选File Watcher。
然后在application:DidFinishLaunching:
中加载Injection的动态库:
1 |
|
再在需要被监视改动的代码文件中添加类重载后的代码执行入口:
1 | + (void)injected |
最后运行工程,当控制台输出“💉 Injection connected 👍”,即表示InjectionⅢ正常运行。
APP运行中,对代码文件做出修改并通过Command+s保存后,被修改文件中的所有类的+injected
及其对象的-injected
方法都会被调用,在方法中直接添加调试代码或调用发生改动的代码,即可对运行中的APP进行动态调试。
3.注意
在使用InjectionⅢ时需要注意以下几点:
- InjectionⅢ只能在模拟器中使用,目前还不能进行真机调试;
- InjectionⅢ动态调试时,新增的类/方法/属性/变量会生效,删除的类/方法/属性/变量仍然可以动态访问;
- InjectionⅢ只监视当前文件的改动,如果要动态新增类,需要在当前文件中新增;
问题记录
Could not find file
记录日期:2020-04-03
错误提示:如下(目标、文件名等已省略)
1 | 💉 *** Compiling /xxx.m *** |
错误原因:PrefixHeader中引用了BaiduMapKit,而BaiduMapKit中对文件的引用(包括BMKPOISearchResult.h),有两处文件名的大小写不正确,导致InjectionⅢ对变动的文件重新编译时失败。
错误分析:XCode中import文件名大小写不正确时会报“Non-portable path”的警告,在InjectionⅢ这儿即导致了重编译的失败,同时信息中也说明InjectionⅢ重编译时使用了PrefixHeader.pch等system headers的编译缓存。