一、前言
做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 下载地址
安装好后启动时,会有一个小针筒的图标
打开
Open Project
,选择你的项目文件夹在
AppDelegate.m
的didFinishLaunchingWithOptions
方法里添加如下代码
#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
就会导致程序闪退,导致这个问题的主要原因是我的项目使用了RAC
,injected
和RAC
在同时使用时会出问题,至于RxSwift
上会不会出问题,需要小伙伴们自己去试一下了。后来新建了一个demo工程,测试成功。
3.这个工具只能在模拟器上运行,真机上不可以
四、原理
Injection
会监听源代码文件的变化,如果文件被改动了,Injection Server会执行rebuildClass重新进行编译、打包成动态库(.dylib),再通过Socket
通知运行的App。Server
会在后台发送和监听Socket
消息,最后通过dlopen把动态库文件载入到运行的App里,返回指针dl
,dlsym
得到动态库的符号地址,就可以处理类的替换了。
本段摘自戴铭的《iOS开发高手课》