Zhihao's Studio.

Swift5新特性

Word count: 1,153 / Reading time: 4 min
2018/05/09 Share

前言

话说这两天好像是Google IO召开的日子,借机蹭一波热度,唱个反调,浅析一下Swift5可能会出现的新特性,也算是为下个月即将举办的WWDC预热预热吧。

ABI稳定性

ABI稳定性这个话题是一个历史遗留任务,最初是Swift3的目标,苹果的拖延症一直拖到了Swift5,还不一定可以实现。这也是国内很多公司不敢全面拥抱Swift的重要原因之一

ABI是啥

ABI是Application Binary Interfaces(应用二进制接口)的缩写,它描述了应用程序和操作系统或其他应用程序的低级接口。

在应用程序运行时,Swift二进制需要和其他库或组件通过ABI进行接触,因此ABI定义了非常底层的细节。比如:如何调用一个函数,数据在内存中是如何存储的、元数据在哪以及如何获取到。

由于现在ABI是不稳定的,因此每一个APP都不得不绑定特定版本的Swift动态库。这样从外面看起来,Swift与App的关联比ios系统要更紧密。

举个例子来说,app1使用的是Swift 4.0,因此它绑定的是包含4.0 ABI的Swift 4.0动态库,而app2使用的是Swift 4.1,它绑定的就是包含4.1 ABI的Swift 4.1动态库。如果ABI变得稳定了,那么ABI就可以抽出来,集成到ios系统中,因为它可以跟Swift的任一版本兼容。

ABI的重要性

通过上面的描述,应该不难看出ABI的重要性了,总结一下ABI稳定性带来的好处吧:

  • App所占的大小会减小
  • Swift变化也没现在这么频繁
  • 版本变化时,更少的改动
  • 因为不需要绑定特定版本的swift,开发者可以做出预编译的框架

但凡事都有两面性,由于带上了ABI这个脚链,不可避免的也会引入一些缺点:

  • 限制了接口的变动
  • Swift的发展和演化需要考虑的东西也渐渐多了起来

Async/Await 模式

熟悉javascript的朋友应该对这个模式不陌生,在ES7中,也加入了这个模式应对异步编程。这个好用的特性,即将引入Swift5!

作用

之前,例如错误处理、回调之类的异步API用起来挺麻烦的,组合调用时很容易产生出复杂的控制流,用Swift的guard let语法糖在闭包调用中看起来重重嵌套,开发者很难知道当前所处的上下文。

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func loadWebResource(_ path: String, completionBlock: (result: Resource) -> Void) { ... }
func decodeImage(_ r1: Resource, _ r2: Resource, completionBlock: (result: Image) -> Void)
func dewarpAndCleanupImage(_ i : Image, completionBlock: (result: Image) -> Void)
func processImageData1(completionBlock: (result: Image) -> Void) {
loadWebResource("dataprofile.txt") { dataResource in
loadWebResource("imagedata.dat") { imageResource in
decodeImage(dataResource, imageResource) { imageTmp in
dewarpAndCleanupImage(imageTmp) { imageResult in
completionBlock(imageResult)
}
}
}
}
}

引入Async/Await模式后,现在的代码如下:

1
2
3
4
5
6
7
8
9
10
11
func loadWebResource(_ path: String) async -> Resource
func decodeImage(_ r1: Resource, _ r2: Resource) async -> Image
func dewarpAndCleanupImage(_ i : Image) async -> Image
func processImageData1() async -> Image {
let dataResource = await loadWebResource("dataprofile.txt")
let imageResource = await loadWebResource("imagedata.dat")
let imageTmp = await decodeImage(dataResource, imageResource)
let imageResult = await dewarpAndCleanupImage(imageTmp)
return imageResult
}

此处应有掌声

Actors

  • Actors是一个新概念,它表示现实世界中的一些概念,比如“一个文档”、“一台设备”、“一次网络请求”等。
  • 它是调度队列、可运行在该队列上并受该队列保护的数据的组合
  • 可以认为是类似于class和protocol的一种新类型
  • 允许开发者在其中定义内部变量/函数从而管理数据、进行相关操作
  • 不能返回值、抛出异常、没有inout参数
  • 开发者可以与之异步通信,Actor可以保证它所保护的数据只被运行于其上的代码接触到
  • UIKit和AppKit可以将主线程建模成MainActor
  • 和class、protocol一样,开发者可以用extension关键字扩展MainActor
  • 当引用数变为0时,Actor生命周期完成

举个例子,假设正在开发一个tableview的应用,内容是一个string数组(受保护数据),代码看起来应该是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
actor TableModel {
let mainActor : TheMainActor
var theList : [String] = [] {
didSet {
mainActor.updateTableView(theList)
}
}
init(mainActor: TheMainActor) {
self.mainActor = mainActor
}
actor func add(entry: String) {
theList.append(entry)
}
}

其他提升

  • String:对正则表达式Language级别的支持、性能提升。
  • 标准库的改进
  • 改进Foundation
  • 增加了新语法

让我们一起静待WWDC2018的到来!

参考

  1. 本文主要翻译自:DeveloperInsider.
  2. Swift库二进制接口(ABI)兼容性研究
  3. Swift 5 的蓝图:ABI 稳定
CATALOG
  1. 1. 前言
  2. 2. ABI稳定性
    1. 2.1. ABI是啥
    2. 2.2. ABI的重要性
  3. 3. Async/Await 模式
    1. 3.1. 作用
  4. 4. Actors
  5. 5. 其他提升