阅读 1059

Swift ABI 稳定后的几个问题

原文链接

ABI 的稳定,会让 Swift 在 Apple 平台上有更大的发展。不过由于历史原因,在系统支持和兼容性方面,我们还会面临一些问题。Swift 官方博客也专门发了一篇文章 Evolving Swift On Apple Platforms After ABI Stability 来进行阐述,来看看他们是怎么说的。

随着 Swift 5 的发布,Swift 的 ABI 也终于稳定下来,并作为 macOS、iOS、tvOS 和 watchOS 核心组件提供。ABI 的稳定所带来的好处很多,最明显的就是 Swift 写的应用不再需要带着 Swift 运行时库一起分发,大大减小了应用的体积。操作系统层面也能更好地集成和优化 Swift 运行时,从而让 Swift 程序启动更快,获得更好的运行时性能,同时降低内存的消耗。而且 Apple 也可以在未来版本的系统中使用 Swift 来提供平台级的 framework。当后续版本的 Swift 能提供模块稳定性时,第三方也可以发布 Swift 编写的二进制 framework。

不过也正是由于 ABI 的稳定,Swift 不再是开发人员工具链的一部分。因此,后续采用新的 Swift 运行时和标准库功能的项目,可能需要新版本的系统。其实 Objective-C 也有这个问题,需要在新的语言特性/框架和老版本系统之间做权衡。

什么类型的语言功能和演进提议可能仅限于未来的操作系统版本?

任何需要新的 Swift 运行时或标准库支持的功能都可能受操作系统可用性限制。这包括:

  • 标准库的附加内容,包括新类型、协议、协议一致性、函数、方法或属性。
  • 对 Swift 类型系统的更改,例如新类型、现有类型的新修饰符(例如函数类型属性)、新桥接、子类型和/或动态转换关系等。

核心小组后续会考虑新提案的后向兼容性影响。

ABI 稳定性是否会影响我们使用 Swift 4.0 或 4.2 模式来维持现有源代码的兼容性?它会影响我将来改用新语言模式的能力吗?

不会。语言兼容性设置是一个纯编译时功能,用于控制源码兼容性。它不会影响到 ABI。我们不需要将 Swift 4 代码迁移到 Swift 5 模式以便使用 Swift 5 的稳定 ABI,并且如果不使用需要新运行时特性的语言功能时,也可以采用新的语言模式而不会强制要求新的系统。

我是否必须使用 Xcode 10.2 重新编译现有的 Swift 应用程序才能在最新的操作系统上运行?

捆绑了 Swift 运行时库的现有 Swift 二进制文件将可以继续在 macOS 10.14.4、iOS 12.2、tvOS 12.2、watchOS 5.2 和未来的 OS 版本上运行。这些应用程序将继续使用捆绑的 Swift 运行时运行,因为这些较旧的 Swift 运行时与稳定的 Swift ABI 不兼容。操作系统中的 Swift 运行时在设计时是与捆绑的 Swift 运行时隔离的,两者都视对方为普通的 Objective-C 类。不过使用捆绑运行时的应用程序无法获得 App Store app thinning 的优势。

我可以选择将新的 Swift 运行时与我的应用程序捆绑在一起,以便能够使用新的运行时功能而无需新的操作系统吗?

由于一些原因,这一点是不支持的:

  • 用于保持与先前稳定版本的 Swift 运行时兼容的共存功能依赖于在单个进程中只有一个 Swift 运行时,并且使用先前稳定版本的 Swift 运行时的代码都是自包含运行时作为应用的一部分。如果允许捆绑新的 Swift 运行时,并与 OS Swift 运行时一起运行,那么新的运行时将无法访问系统中的 Swift 库或与 OS 运行时链接的 ABI 稳定的第三方 Swift 库。
  • 使用捆绑的运行时替换 OS 运行时,将直接规避系统库的安全性,系统库基于其所使用的运行时的操作系统版本进行代码签名。
  • 此外,如果可以替换 OS Swift 运行时,这会导致 OS、Swift运行时、第三方库和应用程序进行测试时,都必须为其配置矩阵添加一个维度。像这样的“DLL地狱”情况使得测试,鉴定和交付代码变得更加困难和昂贵。
  • 将 Swift 运行时库集成在 OS 中,可使其与 OS 的其他组件紧密集成,特别是 Objective-C 运行时和 Foundation 框架。OS 运行时库也可以合并到 dyld 共享缓存中,这样与共享缓存外的 dylib 相比,它们具有最小的内存和加载时间开销。在 OS 之外构建的运行时可能无法完全复制 OS 运行时的行为,或者在限制使用稳定的 API 时这样做可能会带来显着的性能成本。

有没有什么办法可以允许运行时支持新的 Swift 功能向后部署到旧操作系统?

可能可以使用诸如在应用程序中嵌入“填充”运行时库之类的技术来向后部署某些类型的运行时功能。但是,这并非总是可行。成功向后部署功能的能力从根本上受旧操作系统中发布的二进制组件的限制和现有错误的限制。核心小组将根据具体情况逐一考虑新提案的向后部署影响。

关注我们

欢迎关注我们的公众号:iOS-Tips,也欢迎加入我们的群组讨论问题。可以加微信 coldlight_hh/wsy9871 进入我们的 iOS/flutter 微信群。

关注下面的标签,发现更多相似文章
评论