Sendable 协议-Swift 结构化并发的核心安全保障

Sendable 是 Swift 5.5+ 为并发安全 设计的标记协议,核心作用是:告诉编译器「这个类型的实例可以安全地跨 Task/线程传递」,不会引发数据竞争

一、核心本质

  1. Sendable 是「空协议」(无需要实现的方法),仅作为编译期检查标记,不影响运行时性能;
  2. 遵循 Sendable 的类型,要么是「不可变的」(值类型+只读属性),要么是「线程安全的」(如加锁、Actor 封装)。

二、哪些类型默认遵循 Sendable?

无需手动声明,Swift 内置类型已默认遵循:

  • 基础值类型:Int/String/Bool/Double/Array(不可变)/Dictionary(不可变);
  • 原子类型:Atomic(Swift 5.9+);
  • 空元组:()
  • 不可变枚举:无关联值/关联值也遵循 Sendable 的枚举。

三、实用示例

1. 自定义类型遵循 Sendable

场景1:不可变值类型(直接遵循)
swift 复制代码
// 所有属性都是 let(不可变),直接遵循 Sendable
struct User: Sendable {
    let id: Int
    let name: String
    let createTime: Date
}

// 跨 Task 传递:编译器判定安全
Task {
    let user = User(id: 1, name: "张三", createTime: Date())
    Task {
        print(user.name) // 无数据竞争风险
    }
}
场景2:可变类型(需保证线程安全)
swift 复制代码
import OSAtomic

// 可变类:通过原子操作保证线程安全后遵循 Sendable
final class Counter: Sendable {
    private var _count: Int32 = 0 // 原子整型
    
    // 原子操作读写,保证线程安全
    var count: Int {
        get { Int(OSAtomicAdd32(0, &_count)) }
        set { OSAtomicStore32(Int32(newValue), &_count) }
    }
}

2. 编译期安全检查(核心价值)

如果类型不遵循 Sendable 却跨 Task 传递,编译器会直接报错,提前拦截数据竞争风险:

swift 复制代码
// 未遵循 Sendable 的可变类型
struct UnsafeData {
    var value: String // 可变,无线程安全保障
}

// 编译报错:传递非 Sendable 类型存在数据竞争风险
Task {
    var data = UnsafeData(value: "test")
    Task {
        data.value = "error" // ❌ 编译器直接提示错误
    }
}

四、关键使用场景

  1. Task/Async Closure 传参:跨并发任务传递的数据必须遵循 Sendable;
  2. Actor 通信:Actor 之间传递的消息(参数/返回值)必须遵循 Sendable;
  3. 全局变量/缓存:并发场景下的全局数据,标记为 Sendable 保证安全;
  4. 闭包捕获:异步闭包中捕获的变量,编译器会检查是否遵循 Sendable。

五、常见坑点

  1. 可变容器var array: [Int] 是可变数组,不遵循 Sendable;let array: [Int](不可变)才遵循;
  2. 类类型:类默认不遵循 Sendable(即使属性是 let),需手动声明并保证线程安全;
  3. 嵌套类型:嵌套类型需也遵循 Sendable,外层类型才能遵循。

总结

  1. Sendable 是编译期并发安全标记,无实际方法需实现;
  2. 不可变值类型可直接遵循,可变类型需保证线程安全后遵循;
  3. 核心作用:由编译器提前拦截跨线程数据竞争风险,而非运行时处理;
  4. 是 Swift 结构化并发的核心安全保障,异步编程中必须关注。
相关推荐
sakiko_13 小时前
Swift学习笔记28-缓存
笔记·学习·swift
鹤卿12317 小时前
OC UI ——UIGestureRecognizer 手势识别
ui·ios·objective-c
hhb_61819 小时前
Swift技术难点梳理与实战案例解析
开发语言·ios·swift
MonkeyKing20 小时前
iOS UICollectionView 高可用架构:复用、预加载、横向嵌套实战详解
ios
冰凌时空20 小时前
30 Apps 第 2 天:待办清单 App —— MVVM + Combine 响应式 UI
ios·openai·ai编程
冰凌时空20 小时前
手写 Swift 运行时:objc_msgSend 的汇编级解析
ios·openai·ai编程
2601_9560028120 小时前
AdGuardPro_TS.ipa2026最新版ipa 下载后浏览器无广告 官方正版2026最新版pc免费下载(看到请立即转存 资源随时失效)ios必下
macos·ios·cocoa·ipa
Daniel_Coder20 小时前
iOS Widget 开发-12:Widget 深度链接与导航
ios·swiftui·swift·widget·intents
Daniel_Coder21 小时前
iOS Widget 开发-11:Widget 交互按钮实战(iOS 17+ App Intents)
ios·swiftui·swift·widget·link·appintents