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

Swift中continuation.resume传result触发数据竞争警告的修复咨询

问题修复方案

问题根源分析

  1. 类型别名冲突:你自定义的WalletDataResponseBlock<T>与外部框架的同名别名冲突——外部框架的该别名是闭包类型,而你的是Result类型,直接导致代码类型逻辑混乱。
  2. 异步函数语义错误:async throws类型的函数不需要返回Result类型,这类函数的设计语义就是「成功返回值、失败抛错误」,强行返回Result既不符合Swift异步规范,也会引发线程安全风险。
  3. 闭包参数类型错误:networkManager.dataRequest的completion闭包参数类型被错误指定为你自定义的别名,与框架要求的类型不匹配。

修复后的代码

首先删除你自定义的WalletDataResponseBlock<T>别名,避免冲突,然后修改函数实现:

func send<Request, S>(
    request: Request,
    type: S.Type,
    forceRefresh: Bool
) async throws -> NetworkDataResponse<S> where Request: RequestConvertible, S: Decodable {
    return try await withCheckedThrowingContinuation { continuation in
        do {
            let urlRequest = try request.asURLRequest(requestBuilder: requestBuilder)
            self.networkManager.dataRequest(
                urlRequest: urlRequest,
                decoder: JSONDecoder(),
                forceRefresh: forceRefresh
            ) { result in
                switch result {
                case .success(let response):
                    continuation.resume(returning: response)
                case .failure(let error):
                    continuation.resume(throwing: error)
                }
            }
        } catch {
            continuation.resume(throwing: NetworkDataError.error(statusCode: 0, response: (nil, nil, 0)))
        }
    }
}

修复说明

  • 移除冲突的类型别名后,直接使用框架原生的Result<NetworkDataResponse<S>, NetworkDataError>类型,消除类型混淆。
  • 调整函数返回类型为NetworkDataResponse<S>,符合async throws的设计语义,不再传递整个Result对象,从根源避免了数据竞争风险。
  • 提取Result内部的具体值或错误传递给continuation,由于NetworkDataResponse是值类型(元组),传递时会生成副本,天然具备线程安全性。
  • 确保continuation.resume只被调用一次(switch分支覆盖了Result的所有情况),符合withCheckedThrowingContinuation的使用规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:49:55