当前位置: 首页>>编程示例 >>用法及示例精选 >>正文


Swift Sendable用法及代码示例

协议

Sendable

一种类型,其值可以通过复制安全地跨并发域传递。

声明

protocol Sendable

概述

您可以安全地将可发送类型的值从一个并发域传递到另一个并发域——例如,您可以在调用参与者的方法时将可发送值作为参数传递。以下所有内容都可以标记为可发送:

  • 值类型

  • 没有可变存储的引用类型

  • 内部管理对其状态的访问的引用类型

  • 函数和闭包(用 @Sendable 标记它们)

尽管此协议没有任何必需的方法或属性,但它确实具有在编译时强制执行的语义要求。这些要求在以下部分中列出。必须在与类型声明相同的文件中声明符合Sendable

要声明符合 Sendable 而无需任何编译器强制,请编写 @unchecked Sendable 。您对未经检查的可发送类型的正确性负责,例如,通过使用锁或队列保护对其状态的所有访问。未经检查的 Sendable 一致性也会禁用执行一致性必须在同一文件中的规则。

有关Task 所属的language-level 并发模型的信息,请参阅The Swift Programming Language 中的Concurrency

可发送的结构和枚举

为了满足Sendable 协议的要求,枚举或结构必须仅具有可发送成员和关联值。在某些情况下,满足要求的结构和枚举隐式符合 Sendable

  • 冻结结构和枚举

  • 不公开且未标记 @usableFromInline 的结构和枚举。

否则,您需要明确声明符合Sendable

具有不可发送存储属性的结构和具有不可发送关联值的枚举可以标记为 @unchecked Sendable ,在您手动验证它们是否满足 Sendable 协议的语义要求后,禁用编译时正确性检查。

可发送的演员

所有参与者类型都隐含地符合Sendable,因为参与者确保对其可变状态的所有访问都是按顺序执行的。

可发送类

为了满足Sendable 协议的要求,一个类必须:

  • 被标记为final

  • 仅包含不可变和可发送的存储属性

  • 没有超类或将NSObject 作为超类

标有@MainActor 的类是隐式可发送的,因为主要参与者协调对其状态的所有访问。这些类可以具有可变和不可发送的存储属性。

不满足上述要求的类可以标记为 @unchecked Sendable ,在您手动验证它们是否满足 Sendable 协议的语义要求后,禁用编译时正确性检查。

可发送函数和闭包

不是遵循Sendable 协议,而是使用@Sendable 属性标记可发送函数和闭包。函数或闭包捕获的任何值都必须是可发送的。此外,可发送闭包必须仅使用by-value 捕获,并且捕获的值必须是可发送类型。

在期望可发送闭包的上下文中,满足要求的闭包隐式符合 Sendable — 例如,在对 Task.detached(priority:operation:) 的调用中。

您可以通过将 @Sendable 作为类型注释的一部分或在闭包的参数之前编写 @Sendable 来显式地将闭包标记为可发送 - 例如:


let sendableClosure = { @Sendable (number: Int) -> String in
    if number > 12 {
        return "More than a dozen."
    } else {
        return "Less than a dozen"
    }
}

可发送元组

为了满足Sendable 协议的要求,元组的所有元素都必须是可发送的。满足要求的元组隐式符合 Sendable

可发送元类型

Int.Type 等元类型隐式符合 Sendable 协议。

可用版本

iOS 8.0+, iPadOS 8.0+, macOS 10.10+, Mac Catalyst 13.0+, tvOS 9.0+, watchOS 2.0+

相关用法


注:本文由纯净天空筛选整理自apple.com大神的英文原创作品 Sendable。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。