使Xcode可以進(jìn)行運(yùn)行時(shí)調(diào)試功能的工具饿肺,可以理解為把項(xiàng)目變成了Playground。
本文主要針對(duì)戴銘專欄中“App 如何通過注入動(dòng)態(tài)庫(kù)的方式實(shí)現(xiàn)極速編譯調(diào)試斩跌?”進(jìn)行的總結(jié)桩警。
注意
:需要注意第4節(jié)中提到的問題,修改過多地方的話膘滨,盡量還是重啟App來調(diào)試甘凭。
1 安裝和使用
1-1 安裝
最簡(jiǎn)單的方法是從App Store下載安裝InjectionIII,想體驗(yàn)最新feature的也可以從github上下載源碼injectionforxcode
1-2 配置
//appDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//...
[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle"] load];
return YES;
}
啟動(dòng)App后火邓,會(huì)讓我們選擇項(xiàng)目路徑丹弱,選擇后就可以使用了。
修改后不會(huì)立刻生效铲咨,保存才能生效躲胳。
每次保存后,會(huì)自動(dòng)調(diào)用當(dāng)前controller的- (void)injected方法(如果重寫了的話)纤勒。
1-3 查看修改
- 手動(dòng)觸發(fā)
如點(diǎn)擊效果:點(diǎn)一下坯苹。
如布局變化,或網(wǎng)絡(luò)請(qǐng)求:退出當(dāng)前controller摇天,再重新進(jìn)入粹湃。 - 代碼觸發(fā)恐仑,在- (void)injected中手動(dòng)調(diào)用
如布局變了,或網(wǎng)絡(luò)請(qǐng)求:- (void)injected中調(diào)用viewWillLayoutSubviews为鳄、發(fā)送網(wǎng)絡(luò)請(qǐng)求裳仆。
2 原理
- 啟動(dòng)了一個(gè)Mac App監(jiān)聽項(xiàng)目目錄下的文件變化,并與模擬器建立通信
- 項(xiàng)目目錄下的文件發(fā)生變化后孤钦,就重新打包動(dòng)態(tài)鏈接庫(kù)(多個(gè)單文件對(duì)應(yīng)多個(gè)dylib動(dòng)態(tài)庫(kù))
- 項(xiàng)目中InjectionIII Client端歧斟,收到Server端(Mac App)打包完成的socket消息,加載dylib司训,并執(zhí)行Xcode焦點(diǎn)所在.m文件的inject方法构捡。
對(duì)于項(xiàng)目來說,只記錄了動(dòng)態(tài)鏈接庫(kù)的名字和路徑壳猜,而不需要重新編譯和鏈接勾徽。
鏈接器都做了什么
3 注意事項(xiàng)
- 只對(duì)模擬器有效。
- 支持OC和Swift统扳。
- 使用了cocoapods的項(xiàng)目喘帚,如果希望監(jiān)聽pod中源碼的修改,需要設(shè)置Legacy Build System咒钟。
默認(rèn)的New Build System(Default)模式吹由,不編譯pod 里面的改動(dòng)
設(shè)置方法:File -> Workspace Setting -> Build System, 改為L(zhǎng)egacy Build System模式朱嘴。
- 監(jiān)聽另一個(gè)項(xiàng)目時(shí)倾鲫,通過InjectionIII重新選擇監(jiān)聽目錄。
- 不要修改進(jìn)行了swizzling的類萍嬉,否則二次交換乌昔,會(huì)造成死循環(huán)。
4 值得注意的問題
- 不支持方法的刪除:刪除后壤追,方法調(diào)用仍然有效磕道,不拋異常。
- 不支持新增類:新增類引入后使用無(wú)效行冰。但類的重命名是有效的溺蕉。
- 屬性新增、刪除悼做、修改:反射上體現(xiàn)不出來疯特。
在我看來,
問題原因贿堰,可能與蘋果動(dòng)態(tài)庫(kù)調(diào)用的實(shí)現(xiàn)有關(guān)辙芍,不是InjectionIII工具的問題。
因?yàn)檫@些問題在動(dòng)態(tài)庫(kù)打包時(shí)也會(huì)出現(xiàn):修改動(dòng)態(tài)庫(kù)源碼,不修改版本號(hào)故硅,重新打包(清過緩存也一樣)庶灿。
另外,問題原因應(yīng)該與加載時(shí)機(jī)無(wú)關(guān)吃衅,雖然動(dòng)態(tài)庫(kù)的路徑綁定是在main之前進(jìn)行的往踢,而Injection是在didLaunch中才加載的。但是重命名類有效徘层,說明這個(gè)路徑綁定是有效的峻呕。