Swift中continuation.resume传result触发数据竞争警告的修复咨询
问题修复方案
问题根源分析
- 类型别名冲突:你自定义的
WalletDataResponseBlock<T>与外部框架的同名别名冲突——外部框架的该别名是闭包类型,而你的是Result类型,直接导致代码类型逻辑混乱。 - 异步函数语义错误:
async throws类型的函数不需要返回Result类型,这类函数的设计语义就是「成功返回值、失败抛错误」,强行返回Result既不符合Swift异步规范,也会引发线程安全风险。 - 闭包参数类型错误:
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
相关产品推荐
相关产品推荐

