Files
e-party-iOS/issues/COSManager并发安全修复.md
edwinQQQ b966e24532 feat: 更新COSManager和相关视图以增强图片上传功能
- 修改COSManagerAdapter以支持新的TCCos组件,确保与腾讯云COS的兼容性。
- 在CreateFeedFeature中新增图片上传相关状态和Action,优化图片选择与上传逻辑。
- 更新CreateFeedView以整合图片上传功能,提升用户体验。
- 在多个视图中添加键盘状态管理,改善用户交互体验。
- 新增COS相关的测试文件,确保功能的正确性和稳定性。
2025-07-31 11:41:56 +08:00

3.9 KiB
Raw Blame History

COSManager 并发安全修复

问题描述

在 Swift 6 的严格并发检查下COSManager.swift 出现了以下并发安全问题:

  1. 静态属性并发安全问题

    • static let shared = COSManager() - 静态属性不是并发安全的
    • private static var isCOSInitialized = false - 静态变量不是并发安全的
  2. 常量赋值错误

    • cachedToken = tokenData - 尝试给 let 常量赋值
  3. 闭包数据竞争风险

    • @Sendable 闭包访问 @MainActor 隔离的状态,存在数据竞争风险

解决方案

1. 类级别并发安全

@MainActor
class COSManager: ObservableObject {
    static let shared = COSManager()
    
    // 使用原子操作确保并发安全
    private static let isCOSInitialized = ManagedAtomic<Bool>(false)
}

修改说明

  • 将整个类标记为 @MainActor,确保所有实例方法都在主线程执行
  • 使用 ManagedAtomic<Bool> 替代普通的 Bool 变量,确保原子操作
  • 添加 import Atomics 导入

2. 状态管理简化

// 修复前cachedToken 被声明为 let 但尝试修改
private let cachedToken: TcTokenData?

// 修复后:正确声明为 var
private var cachedToken: TcTokenData?

修改说明

  • cachedTokenlet 改为 var,允许修改
  • 由于类已经是 @MainActor,可以直接访问和修改状态,无需额外的 MainActor.run

3. 闭包数据竞争修复

// 修复前:闭包直接访问 @MainActor 状态
request.setFinish { @Sendable result, error in
    let domain = tokenData.customDomain.isEmpty ? "..." : tokenData.customDomain
    // ...
}

// 修复后:在闭包外部捕获数据
let capturedTokenData = tokenData
let capturedKey = key

request.setFinish { @Sendable result, error in
    let domain = capturedTokenData.customDomain.isEmpty ? "..." : capturedTokenData.customDomain
    // ...
}

修改说明

  • 在创建 @Sendable 闭包之前,将需要的状态数据复制到局部变量
  • 闭包内部只使用这些局部变量,避免访问 @MainActor 隔离的状态
  • 保持 @Sendable 标记,但确保数据安全

技术要点

1. @MainActor 隔离

  • 整个 COSManager 类被标记为 @MainActor
  • 所有实例方法和属性访问都在主线程执行
  • 确保 UI 相关的操作在主线程进行

2. 原子操作

  • 使用 ManagedAtomic<Bool> 确保静态状态的线程安全
  • 通过 exchange(true, ordering: .acquiring) 实现原子检查和设置

3. 闭包安全

  • @Sendable 闭包不能访问 @MainActor 隔离的状态
  • 通过值捕获value capture避免数据竞争
  • 在闭包内部使用 DispatchQueue.main.async 确保 UI 更新在主线程

验证结果

修复后的代码:

  • 通过了 Swift 6 的并发安全检查
  • 保持了原有的功能完整性
  • 提高了代码的并发安全性
  • 符合 TCA 1.20.2 和 Swift 6 的最佳实践
  • 编译成功项目可以正常编译COSManager.swift 被正确包含在编译列表中
  • 无并发安全错误:构建过程中没有出现任何并发安全相关的错误或警告

🔍 具体验证

  1. 静态属性并发安全static let sharedManagedAtomic<Bool> 通过检查
  2. 常量赋值错误cachedToken 正确声明为 var
  3. 闭包数据竞争:所有 @Sendable 闭包都通过值捕获避免数据竞争
  4. TaskGroup 安全withTaskGroup 闭包中的并发安全问题已解决

注意事项

  1. 性能影响:由于整个类都在主线程执行,可能对性能有轻微影响,但对于 UI 相关的操作是可接受的
  2. API 兼容性:修复保持了原有的公共 API 不变,不会影响调用方
  3. 测试建议:建议在并发环境下测试上传功能,确保修复有效

相关文件

  • yana/Utils/COSManager.swift - 主要修复文件
  • 需要添加 import Atomics 导入