当年Swift刚发布时,只觉得未来一片光明,因为那时还在上学,代码写的也不算多,还是被忽悠了,而现在Swift都出到第三个版本了,今年六月应该就会发布第四个版本。

入门Swift以来,除了零散的练习外,一共只写了三个项目,实习时完成了第一个,毕业设计时写了第二个,目前正在第三个项目中。前两个是从头开始设计和编写的,基本上没有历史包袱,第三个是从Objective-C转过来的,由于时间太赶,使用了部分的Objective-C代码。常说人的优点与缺点并存,对于一门语言,也应该适用。

1. Swift运行时持续更新

直到现在为止,使用Swift开发的App还需要内置Swift运行时。由于Swfit版本尚未稳定,iOS还未内置Swift运行时。即使iOS11内置了稳定版都运行时,对于iOS8~10系统来说,仍旧需要App内置Swift运行时,这一方面保证了兼容性,让新老版本的Swift App都可以运行在各个系统上。带来的问题中,最明显的还是App体积增大。iOS9带来了App Thinnning,如果启用了BitCode,内置Swift运行时带来的包体积增大问题会减轻一点,而对于iOS8来说,也许就是两份的Swift运行时(32位与64位),目前手上没有iOS8的机器,无法验证。此外最大的问题就是Swift版本迭代时的App开发与测试,如果项目依赖了过多的第三方库,且在新版本Swift还是不兼容老版本,那就需要重写所有不兼容的代码,重新测试。项目大的话,想想都觉得很恐怖。

2.类型推断与代码补齐

要编写Swift应用,需要一台性能良好的主机,如果是难以自行更换固态硬盘的低配版iMac,就很蛋疼了。常见的问题包括Xcode长时间indexing,无响应;Xcode无法进行代码补齐,全部的代码变成白色;长串的类型推断代码导致SourceKit进行占用大量内存与CPU时间;Xcode闪退……

长时间使用Xcode后,已经离不开代码补齐了,Objective-C的编程风格让所有的代码命名变得特别长,没有代码补齐,基本就写不了代码了。到了Swift后,函数命名变得更奇葩了……没有代码补齐,我完全写不了代码了。

类型推断是Swift引入的一个新特性,实际使用中,还是建议每个变量都标明类型,过多的自动类型推断往往是造成代码补齐故障和闪退的主要原因。

另外,如果打开Xcode项目后就闪退,可以尝试清空DerivedData目录。

3. 可选类型

在Objective-C中,大多数对象都可以赋值为nil,不同类型的对象,在赋值为nil后,向它发送消息,或者被忽略,或者返回一个默认值。在Swift中,只有可选类型可以被赋予nil,如果一个隐式拆包的对象,在被访问时并未被赋值过,就会crash。而一些使用Objective-C编写的关联对象,在引入Swift项目后,基本都被当作隐式拆包的对象。

对于一个从网络获取的model,最好每个属性都设置为可选类型,因为我们无法保证每个数据都有值。带来的结果就是需要对每个对象进行拆包,或者设置数据为空时的默认值,比较糟糕的情况是满屏幕的?,??,guard,if let,或者它们之间相互嵌套。Swift上还没有一个完善的模型转换工具,目前使用的是ObjectMapper,带来的大多还是可选类型为nil时的问题。

4. 代码量的变化

Swift有一个很好的特性,就是枚举类型的简化,习惯Objective-C开发的人员,可以在调用枚举数值时,减少很多代码量,此外还可以通过对结构体或对象添加静态成员,使用简化的方式调用变量或数值。如果是习惯纯代码编程的人,应该不会感受到太大的代码量变化。一个UIKit对象,从alloc到配置完成后使用,使用Swift与Objective-C编写的代码行数接近,迁移到Swift后,减少最多的字符,也许只有方括号。Swift的风格还没有统一,在迁移过程中,我还是习惯性地延续了Objective-C的套路。