Swift 和 OC 实现“热加载”
众所周知,Google 推出的跨平台框架Flutter 有着很好的编译优势Flutter Hot Reload
,每次改变之后,点击 reload
就会实现实时编译。那么其实我们也可以实现Swift
和OC
的实时编译。
InjectionIII
通过这个工具可以实现类似Flutter 的快速编译。
实现思路:
Injection 会监听源代码文件的变化,如果文件被改动了,Injection Server 就会执行 rebuildClass 重新进行编译、打包成动态库,也就是 .dylib 文件。编译、打包成动态库后使用 writeSting 方法通过 Socket 通知运行的 App。
安装方式
Mac App Store下载安装
Github
这个工具开发作者是John Holdsworth,作者已经开源了这个工具,地址是https://github.com/johnno1962/InjectionIII
我使用的是在Mac App Store安装的方式,这样比较方便一些,如果你想专研源码,可以去到 GitHub 去研究。
使用指南
打开工程
安装之后打开会出现在 mac 的 menubar 点击打开你目标的工程文件的根目录。
在 applicationDidFinishLaunching加载Injection包
Xcode 10.1:
#if DEBUG Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection10.bundle")?.load()
//for tvOS:
Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/tvOSInjection10.bundle")?.load()
//Or for macOS:
Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/macOSInjection10.bundle")?.load()
#endifXcode 10.2 and later:
#if DEBUG Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle")?.load()
//for tvOS:
Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/tvOSInjection.bundle")?.load()
//Or for macOS:
Bundle(path: "/Applications/InjectionIII.app/Contents/Resources/macOSInjection.bundle")?.load()
#endif
上面是swift版本的NSBundle加载包,下面的代码是oc的实现方法
[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection10.bundle"] load];
运行工程
选择模拟器,cmd+R启动编译
修改文件注入代码
每当对代码进行修改之后,一定要cmd+S保存(不然Injection不会分析变动以及替换符号)实现快速编译。不用重新 cmd+R。
注意事项
还有一点就是如果你在 menubar 打开了这个程式的File Watcher那么就只需要cmd+S 如果你没有开启这个功能,还要多一步命令control
+=
(同时按住 control 和 =)。
还有就是由于沙盒机智,这个方法只能使用在模拟器上,对真机无效。
What's New in LLVM(2017)
Xcode 9中的Apple LLVM编译器具有新的语言特性、改进的诊断和更强大的优化。了解Objective-C和c++的最新添加,了解新的和改进的警告和静态分析器检查,了解LLVM编译器技术如何为应用程序提供更快的构建时间和更好的运行时性能。
1.不同语言的api检查
@available(iOS 11,*)--oc
#available --swift
便捷的方法检查(检查可用性,如果你要给某个新的系统加入新功能)
@interface MyAblumController : UIViewController
-(void)showFaces API_AVALABILITY(ios(11.0));
@end
还可以移动整个类的范围
API_AVALABILITY(ios(11.0))
@interface MyAblumController : UIViewController
-(void)showFaces ;
@end
2.不要把Number元素和标量进行比较
@property NSNumber * photoCount;
-(BOOL)hasPhotos{
return self.photoCount > 0
}
因为这个比较相当于是把photoCount和指针nil相比,返回为YES,所以这个错误很严重。
编译器会报错,提醒你出现了问题,你可以把NSNumber转成interger之后再做判断。
Control Check in Build Setting
设置Suspicious Conversions 为YES(aggressive)当编译器不确定的时候会弹出如上提示。
3. copy修饰NSMutableArray
赋值的时候等于是复制了一个不可变对象,所以以后运行时的时候会报错(如果你对这个数组进行修改)
这个时候就会报错,因为给self.titieArr赋值之后变成了不可变的,所以接下来的操作会导致错误。
解决方法:
//添加setter方法
-(void)setTitleArr:(NSMutableArray *)titleArr{
self.titleArr= [titleArr mutableCopy];
}
每次赋值的时候给数组赋值可变对象。
另外为了及时发现bug可以开启每次build的时候analyze而不是每次都要去手动analyze(如果不开启的话上面的错误不会提示)
设置Analyze During Build 的值为Yes.
4. 声明无参数的函数
Non-prototype declarations in C and Objective-C
非原型声明
在C和OC中意味着foo可以跟任何参数调用,这个行为可以追溯到1977年C语言,不匹配类型的调用会导致运行时的崩溃。
在Xcode9 中编译器带有一个新的警告加强严格原型,会报出警告。
通常只需要在括号中添加void表示不接收任何参数传递。
任何带有参数的调用都会直接报错。
另外block中不接收参数的时候也会出现同样的警告,如下所示。
升级验证警告设置
勾选Yes(Error)
Strict Prototypes 勾选Yes(Error)之前 and 勾选之后
勾选之后就不只是警告了,直接是错误提醒,让你开发的时候不得不注意,也是为了代码的安全性。
结尾
WWDC2017剩余部分是关于C++的优化,如果感兴趣的话可以移步开发者网站观看。
Copyright © 2015 Powered by MWeb, Theme used GitHub CSS.