You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swift严格并发模型中使用关联对象?

在Swift严格并发模型中使用关联对象的替代方案

针对你遇到的全局可变key不符合Swift严格并发要求的问题,以下是几种无需绑定全局actor的解决办法:

方案1:使用静态不可变指针作为关联key

通过创建唯一的不可变指针作为关联对象的key,完全避免共享可变状态。可以利用空类的指针来保证唯一性:

// 定义一个私有空类,用于生成唯一指针
private class AssociationKey {}

extension MyProtocol {
    // 静态不可变的关联key,基于空类的指针生成
    private static let myAssociationKey = UnsafeRawPointer(
        Unmanaged.passUnretained(AssociationKey.self).toOpaque()
    )
    
    var myAddedString: String? {
        get {
            objc_getAssociatedObject(self, Self.myAssociationKey) as? String
        }
        set {
            objc_setAssociatedObject(self, Self.myAssociationKey, newValue, .OBJC_ASSOCIATION_COPY)
        }
    }
}

原理

  • 每个空类的类型指针是全局唯一的,不会和其他关联对象的key冲突;
  • myAssociationKey是静态let常量,属于不可变状态,完全符合Swift严格并发模型的要求,编译器不会抛出并发安全警告。

方案2:用@unchecked Sendable标记全局key变量

如果你想保留原来的全局变量方式,可以通过@unchecked Sendable告诉编译器该变量的实际访问是安全的——因为你从未修改过myKey的内容,只是利用它的内存地址作为key,不存在数据竞争:

// 用@unchecked Sendable标记,说明我们保证该变量的并发访问安全
@unchecked private var myKey: Void?

extension MyProtocol {
    var myAddedString: String? {
        get {
            objc_getAssociatedObject(self, &myKey) as? String
        }
        set {
            objc_setAssociatedObject(self, &myKey, newValue, .OBJC_ASSOCIATION_COPY)
        }
    }
}

注意事项

  • 必须确保永远不会修改myKey的取值,只使用它的内存地址;
  • @unchecked Sendable需要你自行保证安全,若后续不小心修改了变量,会引入数据竞争风险。

方案3:利用静态内部结构体的常量key

可以在属性的get/set方法内部定义静态结构体,用其静态属性作为key,既保证唯一性,又避免全局可变状态:

extension MyProtocol {
    var myAddedString: String? {
        get {
            // 静态结构体的静态属性只会初始化一次,保证key唯一
            struct Key {
                static let value = UnsafeRawPointer(
                    Unmanaged.passUnretained(Key.self).toOpaque()
                )
            }
            return objc_getAssociatedObject(self, Key.value) as? String
        }
        set {
            struct Key {
                static let value = UnsafeRawPointer(
                    Unmanaged.passUnretained(Key.self).toOpaque()
                )
            }
            objc_setAssociatedObject(self, Key.value, newValue, .OBJC_ASSOCIATION_COPY)
        }
    }
}

原理

  • 每个Key结构体的类型指针是唯一的,且静态属性value只会初始化一次;
  • 结构体定义在方法内部,不会产生全局可变状态,符合并发安全要求。

内容的提问来源于stack exchange,提问作者Plastech

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:09:53