ios

iOS 进阶 (二) -- 提升编译调试速度

2019-03-25  本文已影响23人  Q海龙

一、前言

做iOS开发的人都会遇到这样一个问题,每次修改代码后,想看看效果,就得重新Command+R一次,起初项目代码少,重起一次也用不了多少时间,但随着项目代码越来越庞大,重起时所花费的时间越来越多,这就大大降低了开发效率,这种情况在开发UI界面时体验的尤为严重,有时间因为几个像素问题,我们就不得不花1分钟、几分钟甚至更多的时间来看进度条一点点变化。那是否有办法避免这种情况呢,那下面就简单介绍几个工具。

二、工具

1.xcode的Playground

Playground是xcode给开发者提供的代码动态极速调试工具,但它只适用于Swift,Object-c目前使用不了。所以,如果你是Swift开发,可以试着体验一下。

2.Injection Github上开源的第三方工具

Injection是 John Holdsworth 所写的一个开源工具
下载方式:

1.AppStore 搜索 InjectionIII 直接下载
2.Github 下载地址

安装好后启动时,会有一个小针筒的图标

1.png
打开Open Project,选择你的项目文件夹
1.png
1.png
AppDelegate.mdidFinishLaunchingWithOptions方法里添加如下代码
#if DEBUG
    // iOS 
    //[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle"] load];
    //xcode 10+
    [[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection10.bundle"] load];

    // tvOS
    //[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/tvOSInjection.bundle"] load];
    //xcode 10+
    //[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/tvOSInjection10.bundle"] load];

    // macOS
    //[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/macOSInjection.bundle"] load];
    //xcode 10+
    //[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/macOSInjection10.bundle"] load];
#endif

然后在你需要修改的类里添加

- (void)injected {
    //这里将存放你要修改的代码
}

启动编译可以看到控制台打印了
💉 Injection connected, watching /Users/xxx/Documents/InjectionDemo/**
类似这样的信息。接下来我们测试一下,
viewDidLoad方法中设置背景颜色为白色,运行程序、打开模拟器、看到Injection运行成功,然后在injected方法里修改背景颜色为红色,command+s
如果一切顺利就会看到模拟器上的背景色已经换成红色了。

三、使用 Injection 可能会遇到的问题

1.控制台输出的警告

💉 Loading .dylib - Ignore any duplicate class warning...
objc[2708]: Class ViewController is implemented in both /Users/xxx/Library/Developer/CoreSimulator/Devices/xxx/data/Containers/Bundle/Application/xxx/InjectionDemo.app/InjectionDemo (0x109b12d28) and /Users/xxx/Library/Containers/com.johnholdsworth.InjectionIII/Data/eval101.dylib (0x1278d3168). One of the two will be used. Which one is undefined.
💉 Loaded .dylib - Ignore any duplicate class warning...

在Github上的Issues有不少相关问题,但这个问题被开发者认为可以忽略,并不影响功能的正常使用。

2.Command+s 导致 App Crash

我最开始使用时是在自己项目中测试的,每次在injected方法修改后command+s就会导致程序闪退,导致这个问题的主要原因是我的项目使用了RACinjectedRAC在同时使用时会出问题,至于RxSwift上会不会出问题,需要小伙伴们自己去试一下了。后来新建了一个demo工程,测试成功。

3.这个工具只能在模拟器上运行,真机上不可以

四、原理

Injection会监听源代码文件的变化,如果文件被改动了,Injection Server会执行rebuildClass重新进行编译、打包成动态库(.dylib),再通过Socket通知运行的App。Server会在后台发送和监听Socket消息,最后通过dlopen把动态库文件载入到运行的App里,返回指针dldlsym得到动态库的符号地址,就可以处理类的替换了。

1.png
本段摘自戴铭的《iOS开发高手课》
上一篇 下一篇

猜你喜欢

热点阅读