这里每天分享一个 iOS 的新知识,快来关注我吧
前言
随着苹果公司去年发布 Xcode 16,Swift 6 编译器也随之推出。我们在之前也写过一些介绍的文章。
Swift 6 正式发布:从应用到嵌入式,Swift 的新征程!
Swift 6 新特性(一):count(where:) 方法带来的从复杂到简洁变化
这意味着我们可以利用 Swift 6 及其编译时数据竞态保护来创建新项目。但对于许多开发者而言,最大的疑问是:2025 年是否可以全面使用 Swift 6?还是应当继续使用 Swift 5?
在这篇博客中,我不会给出确切的答案,而是分享我的见解和思考,以帮助你决定是否适合在你的项目中采用 Swift 6。这一决定取决于诸多考量,比如如你的项目类型、团队情况以及你对 Swift Concurrency(并发特性)的理解程度。
Xcode 16、现有项目和 Swift 6
如果你在 Xcode 16 中打开一个现有项目,可能不会注意到任何变化。虽然 Xcode 16 默认对所有新项目使用 Swift 6 编译器,但对于老项目,默认依然是 Swift 5 语言模式。
Swift 6 编译器兼容 Swift 5 模式,使其在不强制执行 Swift 6 严格规则的情况下正常运行。
比如,在 Swift 5 语言下,编译时数据竞态保护功能是关闭的。
因此,当我们讨论是否使用 Swift 6 时,我们实际上是在谈论是否选择 Swift 6 语言模式。在 Xcode 16 中打开的老项目会自动使用 Swift 5 语言模式,这就是为什么老项目依然可以编译成功的原因。
新项目的情况
在 Xcode 16 中创建的新项目也默认采用 Swift 5 语言模式。然而,通过 Swift 6 工具链创建的Swift 包 默认使用的是 Swift 6 语言模式,除非被明确配置为其他方式。这一区别非常重要,因为创建新包时,它们的语言模式不同于项目(这是完全可行的做法)。
如果你想要为你的项目开启 Xcode 16 中的并发警告,可以前往 Build Settings,在搜索栏中键入 Strict Concurrency,然后将其改为 Complete:

当你使用 SPM 创建自定义的包时也可以开启严格并发,只需要在 swiftSettings 中加上 enableExperimentalFeature("StrictConcurrency"):
less
let package = Package(
name: "AppCore",
platforms: [.iOS(.v17)],
products: [
.library(
name: "AppCore",
targets: ["AppCore"]),
],
targets: [
.target(
name: "AppCore",
swiftSettings: [
.enableExperimentalFeature("StrictConcurrency")
]
)
]
)
全面使用 Swift 6 的问题和挑战
切换到 Swift 6 语言模式可能会导致原本使用 Swift 5 没有报错的项目编译直接报错,或者运行时崩溃。比如,你可能会遇到关于捕获非可发送参数、可发送闭包和 actor 隔离的问题。
一些问题的修复相对简单,比如将不可变对象明确标记为可发送,或将异步函数中使用的对象重构为 actor。但其他的问题,尤其是涉及跨隔离边界的情况,可能会更加棘手。
比如,为了解决可发送性(sendability)错误而添加 actor 往往需要将同步代码重构为异步代码,这会在整个代码库中产生连锁反应。即使是与 actor 的简单交互也需要 await,即使对于非异步函数也一样,因为 actor 在其独立的隔离上下文(isolation contexts)中执行。
使用 @MainActor 解决错误
常见的解决办法是大量使用 @MainActor 注解。虽然这通过将大部分代码强制运行在主线程上减少了并发相关错误,但并不总是合适的解决方案。这算是一种比较粗暴的解决方案,应谨慎使用。
所以,我们是否应该全面使用 Swift 6?
对于现有项目,我建议谨慎一点。依然使用 Swift 5,除非下边两种情况:
-
你的项目比较小且易于迁移。
-
你对并发概念有较强理解,并有比较多的时间来做适配。
因为 swift 6 是 swift 语言的趋势和未来,与其逃避不如主动去适应,所以对于新项目,可以从一开始就使用 Swift 6 语言模式,但需要做好心理准备,尤其是与那些还没有完全支持并发的苹果框架交互时。
如果你已经开始全面使用 Swift 6 了,我非常想听听你的经验!可以在下边留言分享。
这里每天分享一个 iOS 的新知识,快来关注我吧
本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!