关于Swift 5.1你需要知道的内容
期待已久的 iOS 17.4 和 iPadOS 17.4 刚刚发布,这意味着如果你是一位欧盟 iOS 用户,我们可能会逐渐开始看到其他应用商店出现。除 了 17.4 版本外,Apple 还发布了 Xcode 15.3 和 Swift 5.10。
Swift 5.10 中包含的提案数量并不多,但这并不会让此版本显得不那么重要。
借助 Swift 5.10,Apple 设法弥补了 Swift 并发数据安全功能中存在的一些重大差距。简而言之,这意味着编译器将能够通过在更多地方强制执行 actor 隔离和可发送性来捕获更多可能的线程安全问题。
我们来看看实现此功能的两个特性。
增强的并发性检查
我之前写过有关 严格并发性检查 的文章,但当时你的代码仍然有一些可能不安全的方式,而编译器不会注意到。在 Swift 5.10 中,Apple 修补了这些情况,现在编译器将在严格并发模式下正确标记所有不安全的代码。
当然,这排除了你已标记为 nonisolated(unsafe)
或 @unchecked Sendable
的代码,因为这两个标记都表示代码 应该是安全的,但编译器无法检查这一点。
如果你已使用严格并发性检查并已解决所有警告(如果你做到了,向你致敬!这并不简单),那么 Swift 5.10 可能会标记你可能错过的某些极端情况。
在我看来,更好的编译时检查以防止数据竞争是对该语言的受欢迎改进,我迫不及待地想看看 Apple 在不久的将来会对严格并发性检查做出哪些其他改进。目前有一些提案旨在解决严格并发性检查的可用性,在我看来这是一件非常好的事情。
SE-0412 全局变 量的严格并发性
提案 SE-0412 已进入 Swift 5.10,它进一步增强了 Swift 在编译时防止数据竞争的能力。
当你编写涉及共享状态的代码时,如果你不确保此共享状态可以跨线程安全使用,那么你就会让自己面临来自许多位置的数据竞争。
在 Swift 5.10 中,只有在以下情况下,编译器才会允许你从并发上下文访问共享的可变状态:
- 此状态不可变且可发送(在此处了解有关可发送的更多信息)
- 此状态隔离到全局 actor(如
@MainActor
或你编写的 actor)
在任何其他情况下,编译器都会认为从并发上下文中访问共享状态是不安全的。
如果你采取了规避 Swift 并发的 actor 和可发送性的措施(例如,因为你正在使用 Semaphore 或 DispatchQueue 来同步访问的旧代码),你可以通过将全局变量标记为 nonisolated(unsafe)
来选择退出并发性检查。此标记将告诉编译器它不需要对标记的属性执行任何安全检查;你已确保代码可以安全地从并发上下文中使用。
将属性标记为 nonisolated(unsafe)
很像强制解包属性。你可能确信你的代码是安全的并且会按预期工作,但你只能依靠自己。你已告诉编译器你了解自己在做什么,并且不需要编译器为你执行任何检查。
每当你想要使用 nonisolated(unsafe)
时,你都应该始终问问自己,是否可以实际将你正在标记的类型隔离到全局 actor,或者也许你可以将属性的类型设为 Sendable
和不 可变。
总结
Swift 5.10 是对该语言非常受欢迎的改进,它使 Swift 并发比 Swift 5.9 中的并发稍微更可靠。Swift 6.0 正在逐渐开发中,我认为当 Apple 宣布 iOS 18、Xcode 16.0 等时,我们会在 6 月左右看到第一个 Swift 6.0 测试版。
我很高兴看到 Apple 致力于并发,并在每次发布中进行(有时是急需的)改进,在我看来,Swift 5.10 是在为我们的异步代码实现编译时安全性方面的一个极好的里程碑。