Ecosystem

Code Size

binary_size

苹果官方一直在跟踪使用 Swift 时二进制中代码段的尺寸大小,并与 Objective-C 进行比较。从 Swift 4 的接近 OC 2.5 倍到现在 Swift 5.3 的 1.5 倍。

当使用 SwiftUI 时的尺寸变化情况呢?

swift-ui-bisize

这里拿了一个简单的应用举例,迁移后大概减少了 40% 以上的尺寸。

来了解下内存的优化,我们知道 clean memory 在运行时可以被擦除在需要时再重新加载,而 dirty memory 则是应用在运行时分配和操作的内存。接下来会看一下 dirty memory 使用率是如何改善的。

与基于引用类型的语言相比,Swift 使用值类型具有一些基本优势。

这里先以 Objective-C 为例,一个具有 UUID,字符串和数字的简单模型类型。当一个数组存储其对象时,存储的是指针,其对象又拥有其属性的指针。在 OC 中对于短的 ASCII 字符串,可能会存储在指针中来减少额外的内存分配,其最终内存中情况如下:

objc-memory-layout

然后,我们来看 Swift 相同的情况,Swift 对值类型的使用避免了通过指针访问其中许多值的需要。

同时,Swift 的字符串可以容纳更多字符,包括非 ASC 字符,所以 UUID 也可以直接存储在结构体中。最终,几乎所有的内容都保存在一个连续的内存块里。

swift-memory-layout

通过使用这样的值类型,Swift 程序可以获得显着的内存收益。

当我们检查有 400 个模型对象时的内存占用情况可以看到下面的对比:

memory-chart

尽管有这个优点,但是某些 Swift 程序仍然由于运行时开销而使用更多的内存。在之前,Swift 在启动时创建了许多缓存以及内存占用,这些缓存存储了比如协议一致性信息和其他类型信息以及用于将类型转换到 OC 的数据。这些使得 Swift 运行时的开销过大了一些。

这也是苹果优化的重点。在 Swift 5.3,内存的使用情况已经减少为不到之前的 1/3。

swift-memory-reduce

另外,为了减少 Swift 运行时用户空间内存占用苹果还进行了另一项重要更改,Swift 标准库被移动到系统库中 Foundation 的下层。

Diagnostics

Swift 编译器具有新的诊断策略,可以发现问题的原因。其得益于编译器中新的诊断子系统:

  • 新的定位代码问题的策略
  • 更精确和可操作的错误类型

诊断问题时,编译器还会在内部记录有关问题的更多信息,因此它现在会产生更多的注释。如果想了解更多关于新的诊断架构的信息,可以去 Swift.org 中看更多详细的介绍: New Diagnostic Architecture Overview

Code Completion

Swift 的代码补全现也得到了显著改善,首先是类型检查的推断。

type-checking

这个例子我们看到,在不完整的字典字面量编写时,编译器推断了三元表达式中的值。

下面这个例子则是编译器也能很好的提示某些动态特性的内容,比如将 KeyPath 作为函数:

keypath-as-function

除了代码提示结果的质量外,与 Xcode 11.5 相比,在某些情况下,其性能则有 15 倍的提升(不过没说哪些情况~)。

SwiftUI 代码的补全推断性能也提升了很多。

swiftui-completion

Code Indentation

Xcode 中的代码缩进(同代码补全一样,也由开源 SourceKit 引擎提供支持)已得到显着改善。

代码缩进格式主要改善有:

  • 链式方法调用
  • 调用参数
  • 元组元素
  • 跨多行的集合元素
  • 多行控制流语句

在这里,官方又举了一个 SwiftUI 链式调用的例子(还是刚才的 MovieSwiftUI 项目)

swiftui-indentation

Debugging

当调试信息可用时,调试器现在将显示常见 Swift 运行时故障的原因,而不仅仅是显示无效指令崩溃。

此外,Swift 的调试支持现在总体上更加健壮。

lldb-debug

为了理解原因,让我们看一下 Swift 在编译时与 Objective-C 互操作的方式。Swift 使用 clang 模块从 Objective-C 导入 API 来解析有关类型和变量,LLDB 需要导入在当前调试上下文中可见的所有 Swift 和 clang 模块。

尽管这些模块文件具有大量有关类型的信息,但由于 LLDB 具有整个程序及其所有动态库的全局视图,因此导入 clang 模块有时会以编译时无法实现的方式失败。

dwarf-debug

作为备用,当发生这种情况时,LLDB 现在还可以从 DWARF 调试信息中导入 C 和 Objective-C 类型到 Swift 中调试。这极大地提高了诸如 Xcode 变量视图和表达式评估器之类功能的可靠性。

Swift on AWS Lambda

Swift 是一种出色的通用语言,因此它非常适合在 Apple 平台上构建应用程序,但也适用于许多其他任务。

现在 Swift 支持的平台有:

  • Apple 各平台
  • Ubuntu 16.04,18.04,20.04
  • CentOS 8
  • Amazon Linux 2
  • Windows (Swift 5.3)

AWS Lambda 也是 Swift 需要支持的平台。

Serverless 函数是客户端应用程序开发人员将其应用程序扩展到云中的一种简便方法。现在,可以使用开源的 Swift AWS Runtime 来做 Serverless 开发。

aws-lambda

Language

Swift 语言层面有很多新特性,如下图:

new-features

Multiple trailing closure syntax

在之前的 Swift 版本,尾随闭包只允许最后一个参数,新的版本则允许多个尾随闭包,以一个 UIView 的动画为例:

multiple-trailing-closure

这种多个尾随闭包的语法也非常适合 DSLs。这里举了一个 SwiftUI 的例子:

closure-for-dsls

KeyPath as function

在 Swift 4.1 引入了 KeyPath。在新的版本中则可以使用其来作为函数,前面的代码补全提示也有类似例子。

keypath-as-func

@main

在之前版本的 Swift,我们使用 @UIApplicationMain 来告诉编译器隐式生成 main.swift 来运行应用程序。在 Swift 5.3 中,苹果对该功能进行了概括和推广。

比如在编写命令行程序时,我们可以使用 @main 来生成程序入口点。

@main

Increased availability of implicit self in closures

一般在闭包中,我们要显式的声明 self,并且访问属性时也要通过 self.xx 的方式,而新的版本则在闭包中对结构体或枚举增加隐式的 self,使用时如下所示:

implicit-self

Multi-pattern catch clauses

从历史上看,catch 语句的表现力不如 switch 语句,导致人们诉诸于 catch 子句中嵌套 switch。

在 Swift 5.3 中则添加了多子句模式匹配 catch error 的方式:

multi-pattern-catch

这使您可以将这种多子句模式匹配直接平化到 do catch 语句中,使其更易于阅读。

Enum Enhancements

首先,Swift 5.3 起编译器可以对枚举值进行比较。

enum-compare

然后是枚举 cases 作为协议的 witnesses。

enum-case-as-protocol-witness

Embedded DSL Enhancements

去年,Swift 增加了对嵌入式 DSL 的支持,以增强 SwiftUI 的声明性语法。在Swift 5.3 中,苹果扩展了嵌入式 DSL,以支持模式匹配控制流语句,比如 if let 和 switch。

dsl-enhance

另外,编译器现在会对 builder 进行推断,比如假设一个属性 body 需要进行标记:

@SceneBuilder var body: some Scene {
    //...
}

在 5.3 中,我们不再需要显式地声明标记:

embedded-dsl-enhance

Library

SDK

Float16

从 Float16 开始,Float16 是 Swift 5.3 的新 IEEE 754 标准浮点格式。Float16 仅占用两个字节的内存,而单精度浮点数占用四个字节。由于它只有一半大小,因此可以在 SIMD 寄存器或内存页中容纳两倍的数量,而在支持的硬件上,这通常会使性能提高一倍。但是请注意,作为较小的数据类型,它的精度和范围也更加有限。

float16

Apple Archive

Apple Archive 是什么呢?

  • 模块化的归档格式
  • 多线程快速压缩
  • 与 CLI,Finder 可交互
apple-archive

在上面例子中的文件流构造函数中,引入了另一个新库:Swift System

swift-system

Swift System 包装了很多使用比如强类型的 RawRepresentable 结构体,错误处理,默认参数,命名空间和函数重载之类的技术的 API。从而为 Swift SDK 的系统层奠定了基础。

OSLog

在 Swift 5.3 中,苹果利用了复杂的编译器优化功能,使 OSLog 更快,更富有表现力,并增加了对字符串插值和格式设置选项的支持。

oslog

如果您仍将 print 用作日志记录解决方案,那么现在是重新考虑的最佳时机。

Packages

Swift Numerics

Swift Numerics 是一个新的用来数值计算的库。Swift Numerics 定义了所有基本的数学函数(例如正弦和对数),这对于通用上下文以及对复数和算术的支持都更加有用。

numerics

Swift ArgumentParser

Swift ArgumentParser 也是一个新的开源 Swift 库,用于命令行参数解析。

argument-parser

Swift StandardLibraryPreview

预览包提供对 Swift 未来功能的访问。

library-preview

这些库都在 GitHub 开源,苹果官方鼓励所有的开发者们都能积极使用并参与讨论。

以上就是这个 session 的全部内容,原版视频可以去 官网 - session 10170 或者 Developer 应用中查看。