Sendable

16 阅读1分钟

1: 值类型:只需声明

struct Article: Sendable {
    let id: Int
    let title: String
}

2: 引用类型 final 所有属性是不可变的 let 所有存储属性都符合sendable

final class User: Sendable {
    let id: String
    let age: Int
    init(id: String, age: Int) {
        self.id = id
        self.age = age
    }
}

3: 当类型包含”不安全“属性时: @unchecked Sendable : 明确告诉编译器你将以其他方式(比如自己用锁管理)保证安全,编译器不再检查,需谨慎使用

class UnsafeWrapper: @unchecked Sendable {
    private let queue = DispatchQueue(label: "com.example.serial")
// 自己用queue同步所有访问
}

4: @sendable闭包 在并发上下文中如task中传递闭包,改闭包是@sendable

这要求:

1 闭包不能捕获可变的变量

2 所有捕获的变量必须符合sendable协议

var mutableCounter = 0 // 非sendable ,因为可变

Task {

    // 错误;无法捕获inout 参数或可变变量

//    let closure: @Sendable() ->Void = {

//        print(mutableCounter) //Reference to captured var 'mutableCounter' in concurrently-executing code

//    }

    let immutableCopy = mutableCounter // 复制一份类型✅

    let safeClosure: @Sendable () ->Void = {

        print(mutableCounter)

    }

}

// 编译器检查设置 xcode buildsetting

Minimal (默认):仅对明确标为 Sendable 的代码发出警告。

Complete:对所有可能跨并发域传递的代码进行严格检查。建议在新项目中启用以提升安全性。

// 应用场景:

// task间传递数据 作为actor的方法参数或返回值 在AsyncSequence 或AsyncStream 中传递使用