iOS学习iOS Developer

2017GMTC Swift在Airbnb的应用实践

2017-07-10  本文已影响97人  雨_树

主要分享了Airbnb使用Swift的一些经验,Airbnb的Swift代码的使用已占大约80%~90%,算是业界比较多的了。

Swift的主要特性以及在Airbnb的应⽤

安全
Swift使用Optional Variable区分是否为空,TT?为不同的两个类型,使用WrapUnwrap进行转换

对于let vs var,尽量使用不可变的let

Swift提供了高级枚举类型,使得enum变得异常强大,可以支持之前传统上只有类才可以支持的特性,比如计算属性、实例方法、初始化、扩展、协议等。

Protocol Oriented Programming
这个之前没有注意,但事实上Swift整个语言与OC已经截然不同,OC依然是传统的面向对象编程,而Swift已经是面向协议的编程。

可以通过ASIHttpRequestAFNetworking各自实现网络请求的方式来比较

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWrong:)];
[request startAsynchronous];

ASIHttpRequest是面向对象的,你需要实现一个对象的实例,设置属性,调用对应的方法。

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"www.olinone.com" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    
}];

AFNetworking是面向协议的,你可以看到这里只需要对方法进行直接调用,而不需要了解对象的属性。

我们自己在使用Swift的转换中,似乎还没有意识到这一点。

泛型
在可能处理多种类型的地方使用泛型:


这里类型可能会有如下三种:
CarouselComponent<HomeCardComponent>
CarouselComponent<ExperienceCardComponent>
CarouselComponent<GuidebookComponent>

其他特性
Memory Management:全部是ARC
Less Code:没有.h .m
Faster: Struct 使用栈,Class使用堆;Swift的Copy Write在堆上面
Tuples:支持多元组,不同类型的集合
Access Control:OC的动态特性破坏了访问控制,而Swift不支持动态特性

Airbnb遇到的问题以及解决方案

编译时间

Airbnb在开发的过程中编译的时间越来越长,发现是由于Swift进行“类型推导以及类型检查”时耗费了大量的时间。

如何调试编译时间,发现占时过多的方法:

target -> Build Settings -> Other Swift Flags 添加编译设置
-Xfrontend -debug-time-function-bodies

在“times.txt”文件中查看各个方法的耗时,下面的命令可以排序
xcodebuild -workspace yourWorkspaceName.xcworkspace -scheme schemeName clean build 2>&1 |egrep "d.dms"|sort -nr > times.txt

根据检查出来的问题,总结了一些有针对性的解决方案:

  1. Use CI system to monitor the build time.
  2. Educate engineers to provide type information as much as possible.
  3. Use Lint to prevent engineers from common issues.
  4. Offline type inference (Use SourceKit).

BUCK
使用BUCK编译系统来提高编译速度(并行编译、增量编译、缓存编译中间结果、开源)

Whole Module Optimization

全模块优化WMO的原理就是在编译项目时,将所有源代码合起来作为一个整体进行分析和优化,与单文件优化SFO(Single File Optimization)相区别,通过排除死函数、去inline函数调用等优化最终的目标文件,可以数倍的提高性能。

这篇文章评测 Swift 3.0 项目编译优化选项对编译速度的影响研究了三种模式的编译时间:

这里比较有趣的一点是WMO作为优化了的编译方式,所花的时间比不优化的还要快,官方的解释是既优化了性能,又优化了编译速度(好吧~)

WMO在Release默认打开,但是在Debug默认关闭,这是因为WMO的增量编译做的不好:改动一个文件后,编译器还得把所有的文件再编译一遍。

此外,针对WMO,这篇文章优化 Swift 编译速度有更深入的分析:把所有Model文件全部合并到一个文件去编译,这样做的效率提升超过了WMO。

这是因为,WHO除了合并文件之外,还会在预编译阶段做一些事情,包括:检测并去掉没有被调用的方法和类型;给没有被继承的类或方法加上final标签,优化为静态调用或者内联进去。

这些优化可以大幅提升程序的效率,但是导致在编译阶段每合并一个文件,就会遍历所有文件进行一次检查,使得编译时间过多。 这里采用了一个比较“Tricky”的方法做到只合并文件,不做优化

这种方法解决了上面的问题,不过之前增量编译的问题同样存在:增量编译的颗粒度从File级别增大到Module级别。

Airbnb这里采用的就是这种方法,不过,这种方法对Airbnb很有用,是因为:Airbnb有70个左右的类库,这在某种程度上降低了增量编译的颗粒度级别。但是对于我们这种只有一个Target的工程来说,好处不大。

启动性能

Airbnb通过下面的方法调试启动性能:


动态库合并

Dynamic Library Merging

Airbnb通过这些操作,减少了12M的安装控件,以及降低了50%的"Pre-main Time"

Swift和Objective-C混用

提到了两点

为了与Swift中可选对象对应,OC提供nullable, nonnull

问题

1 改一个文件,从0开始编译,增量编译有没有影响?更慢?
所有的文件都放到一个里面编译,不加选项的话,就是单个文件。所以增量编译是没有优势的,但是要rebase的话不一样。 Airbnb有七十多个类库,所以可以使用这种方法。

2 设计方法的时候,如何取舍加空或不加空?
不加空最好:避免出错,性能

3 SwiftLint是一个用来规范代码的工具

上一篇下一篇

猜你喜欢

热点阅读