iOS 如何擁有熱重載極速調(diào)試?

?? 只適用于模擬器上調(diào)試,真機(jī)無(wú)效
1、Mac的App Store上下載安裝 InjectionIII,安裝好之后,打開工具運(yùn)行,會(huì)在桌面頂部狀態(tài)欄,初始狀態(tài)是藍(lán)色,配置好之后是橘紅色
2、打開InjectionIII,Open Project,選擇你的項(xiàng)目目錄
3、選擇的項(xiàng)目會(huì)在Open Recent中出現(xiàn),保持File Watcher的選項(xiàng)勾選,如果有多個(gè),要保持當(dāng)前運(yùn)行的項(xiàng)目在第一個(gè),之后可以快捷選擇。
4、在AppDelegate的DidFinishLaunchingWithOptions配置InjectionIII的路徑
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    #ifdef DEBUG
    //InjectionIII 注入
    //oc
    [[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle"] load];
    //switf
    Bundle(path:"/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle")?.load()
    #endif

    return YES;
}
5、在需要?jiǎng)討B(tài)調(diào)試的頁(yè)面控制器中寫上injected方法,把需要操作的UI方法添加到injected中執(zhí)行,如果想讓全部的控制器都能使用,直接添加到BaseViewController
// Objective-C:
- (void)injected {
    #ifdef DEBUG
        NSLog(@"I've been injected: %@", self);
        [self viewDidLoad];
    #endif    
}
// Swift
@objc func injected() { 
    #if DEBUG 
        print("I've been injected: \(self)")
        self.viewDidLoad() 
    #endif 
}
6、修改完UI,直接cmd + S就能看到效果,部分頁(yè)面可能耗時(shí)比較久或無(wú)法使用,正常頁(yè)面均能使用

iOS擁有熱重載的原理:

Injection for XCode
GitHub地址:https://github.com/johnno1962/InjectionIII

  • Injection工具可以動(dòng)態(tài)地將iOS代碼在已運(yùn)行的程序中執(zhí)行, 不用重啟.
  • Injection會(huì)監(jiān)聽源代碼文件的變化, 如果文件被改動(dòng)了,
  • Injection Server就會(huì)執(zhí)行rebuildClass重新進(jìn)行編譯、打包成動(dòng)態(tài)庫(kù).dylib文件,
    編譯、打包成動(dòng)態(tài)庫(kù)后, 使用writeString方法通過(guò)Socket通知運(yùn)行的App.
- (BOOL)writeString:(NSString *)string {
    const char *utf8 = string.UTF8String;
    uint32_t length = (uint32_t)strlen(utf8);
    if (write(clientSocket, &length, sizeof length) != sizeof length ||
        write(clientSocket, utf8, length) != length)
        return FALSE;
    return TRUE;
}
  • Server會(huì)在后臺(tái)發(fā)送和監(jiān)聽Socket消息, Client也會(huì)開啟一個(gè)后臺(tái)去發(fā)送和監(jiān)聽Socket消息.
  • Client接收到消息后會(huì)調(diào)用inject(tmpfile: String)方法, 運(yùn)行時(shí)進(jìn)行類的動(dòng)態(tài)替換(新類動(dòng)態(tài)替換舊類).
  • dlopen會(huì)把tmpfile動(dòng)態(tài)庫(kù)文件載入運(yùn)行的App里, 返回指針dl.
  • 接下來(lái), dlsym會(huì)得到tmpfile動(dòng)態(tài)庫(kù)的符號(hào)地址, 然后就可以處理類的替換工作了.
  • 當(dāng)類的方法都被替換后, 我們就可以開始重新繪制界面了.
  • 使用動(dòng)態(tài)庫(kù)方式極速調(diào)試, 整個(gè)過(guò)程無(wú)需重新編譯和重啟App.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容