2019 年春天,Swift 5 随 iOS 12.2 发布后,奇怪的事情发生了。什么都没做,应用体积却缩小了几 MB。 Swift ABI Stability and More
本文接续上一篇文章 Swift 深入解析 #8。
秘密就在发布说明中干巴巴的一行字里:实现 ABI 稳定性。
Swift 系列的最后一篇将讲清这件事的来龙去脉:ABI 是什么、为什么花了 5 年,以及它带来了什么可能。
这是语言历史与底层结构交汇的地方,很适合作为系列的收尾主题。
什么是 ABI — 二进制之间的约定
大家都知道 API,它是源代码层面的约定:函数叫什么、参数是什么。
ABI(Application Binary Interface)是更底层的约定,即编译后二进制之间的约定。
它规定调用函数时参数放入哪些寄存器、struct 如何布局在内存中(布局篇中见过的那些尺寸)、符号如何命名(名称修饰),以及在哪里查找元数据。
为什么这个约定很重要?因为在不同时间、使用不同编译器构建的两个二进制必须能够协同工作。
应用与操作系统内置库的关系正是如此。如果 ABI 随版本变化,用 Swift 5.0 构建的应用就无法与 Swift 5.5 运行时通信。 Swift ABI Stability and More
Swift 早期确实如此。ABI 每个版本都会变化,因此每个应用都必须完整携带所使用版本的 Swift 运行时和标准库。
每个应用都要承担几 MB 的重复负担,操作系统也无法在自己的框架中使用 Swift,因为系统框架还必须与未来的应用通信,而当时没有这种保证。
Swift 5 的 ABI 稳定性声明冻结了这一约定。调用约定、类型布局和名称修饰都已确定,后续版本会在遵守这项约定的前提下演进。 Swift ABI Stability and More
标准库随即迁入操作系统(从应用中移除后,体积便缩小)。Apple 也因此能够用 Swift 构建 SwiftUI 等系统框架。
2019 年的体积缩减,其实是这门语言走向成熟的信号。 Swift ABI Stability and More
为什么花了 5 年 — 冻结的重量
要回答“为什么不早点冻结”,必须看看冻结的代价。确定 ABI 就意味着连当时的设计错误也要永远承担。
一旦约定了布局和规范,只要已有二进制仍然存在,就无法修改。
回想一下 Swift 1~4 时期有多么动荡。语法几乎每个版本都被重做。如果当时冻结,今天的 Swift 就会被困在早期设计的牢笼中。 Swift ABI Stability and More
我们一直等到泛型实现稳定、值类型布局策略得到验证,也等 Evolution 流程(哲学篇第 4 集)解决重大设计争论,前后用了 5 年。
看看 C++ 因数十年的 ABI 惯性而拒绝改进方案的案例,就能理解这种谨慎的价值。
第二个约定 — 模块稳定性与库演进
不过,ABI 稳定性仍留下一个问题:二进制框架的分发。
Swift 5.0 之前的编译器使用名为 swiftmodule 的二进制格式交换模块接口,但它与编译器版本绑定。 Swift ABI Stability and More
Xcode 一升级,所有已分发的 SDK 就会全部失效。
Swift 5.1 的模块稳定性解决了这个问题。它引入了基于文本的稳定接口文件(.swiftinterface),从而可以读取使用其他版本编译器构建的框架。 Swift ABI Stability and More
基于 XCFramework 分发 SDK 的生态(支付、分析和地图 SDK)就建立在此基础之上。
与之配套的概念是库演进模式。它提供一个选项,使框架即使之后新增存储属性,也不会破坏现有应用,但代价很有意思。
该模式下的 public struct 会成为布局未确定的 resilient type。客户端无法在编译时知道它的大小,并要承担间接访问的成本。
这正是布局篇中“知道大小就更快”的反命题。
因此,演进模式提供了一个名为 @frozen 的出口:“冻结这个类型的布局,但允许直接访问。”标准库中的 Int 和 Optional 是 @frozen,原因就在这里。
对应用开发者来说,实际意义如下:应用 target 和源码分发包(大多数 SwiftPM 包)不需要此模式,开启它反而会吃亏。
只有以二进制形式分发 SDK 的一方才需要开启。问题“BUILD_LIBRARY_FOR_DISTRIBUTION 是什么?”的答案就在这一段。
收尾 — 贯穿整个系列的一个故事
ABI 成为 Swift 系列的最后一篇是有原因的。到目前为止介绍的概念都在这里汇合。
值类型的布局(值篇、布局篇)被冻结后,struct 才能跨越二进制边界。witness table(分派篇)的格式确定后,协议才成为框架 API。
而 Evolution 流程(哲学篇第 4 集)让设计走向成熟,也让我们有信心将其冻结。
通过类型保证安全(可选值、ARC、Sendable),明确成本(unsafe、any、@unchecked),并将复杂性分成阶梯(Progressive Disclosure)。
这些原则从语法层一直贯穿到二进制层并保持一致,这就是整个系列想表达的故事。
Swift 现在仍在 Evolution 论坛上构建下一层阶梯。希望这个系列能成为你自行读懂这些变化的地图,我们就此收尾。
总结
- ABI 是二进制之间的约定(调用约定、布局和名称修饰),并在 Swift 5(2019 年)中被冻结。因此,标准库迁入操作系统,应用体积缩小,Apple 也能够用 Swift 构建 SwiftUI。
- 冻结花了 5 年,因为这意味着要永远承担设计错误。这段时间用于等待泛型、布局和 Evolution 流程成熟。
- Swift 5.1 的模块稳定性(.swiftinterface)开启了基于 XCFramework 的二进制框架生态。
- 库演进模式以间接访问成本为代价,换取框架演进时应用仍不崩溃,而 @frozen 就是这个出口。对于应用 target,这是不必要的选项。
- 系列结论:Swift 关于类型化安全、明确成本和分阶复杂性的原则,从语法到二进制始终一致。 Swift ABI Stability and More
来源与核验标准
- Swift ABI Stability and More — Swift.org · 官方发布 · 核验日期 2026-08-17 · 依据:Swift 5 ABI 稳定性、操作系统搭载运行时以及应用体积变化

![[Swift 深入解析 #9] Swift ABI 稳定性:2019 年应用体积缩小的原因 封面图](/assets/images/posts/150f67d8-49bc-4461-8f04-26b5e8fc56e3/swift-abi-stability-app-size.jpg)