升级Xcode14.3后遇dataTask歧义及resume调用失败问题求解决
Xcode 14.3升级后网络请求相关错误的解决方法
错误2:Value of type 'T.URLSessionDataTaskProtocol' has no member 'resume'
问题原因
URLSessionDataTaskProtocol协议未定义resume()方法,而NetworkManager中调用了task.resume(),编译器无法确认关联类型是否具备该方法。
解决方法
给URLSessionDataTaskProtocol添加resume()方法要求,并让系统的URLSessionDataTask遵循该协议:
// 定义包含resume方法的协议 protocol URLSessionDataTaskProtocol { func resume() } // 让系统的URLSessionDataTask遵循协议 extension URLSessionDataTask: URLSessionDataTaskProtocol {}
错误1:Ambiguous use of 'dataTask(with:completionHandler:)'
问题原因
URLSession扩展中实现的协议方法与系统自带的dataTask(with:completionHandler:)签名完全一致,编译器无法区分;同时扩展内的实现递归调用自身,进一步加剧了歧义。
解决方法
- 明确协议的关联类型,并补充实现所有协议要求的方法
- 在扩展中明确调用系统原始方法,避免递归
修改后的URLSessionProtocol和URLSession扩展代码:
protocol URLSessionProtocol { associatedtype DataTaskType: URLSessionDataTaskProtocol func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> DataTaskType func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> DataTaskType } extension URLSession: URLSessionProtocol { // 指定关联类型为系统的URLSessionDataTask typealias DataTaskType = URLSessionDataTask // 实现URL版本的dataTask方法,调用系统原始方法 func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask { return super.dataTask(with: url, completionHandler: completionHandler) } // 实现Request版本的dataTask方法,调用系统原始方法 func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask { return super.dataTask(with: request, completionHandler: completionHandler) } }
验证修改
完成上述修改后,NetworkManager中的task.resume()调用会被编译器识别(因为DataTaskType遵循了带resume()方法的协议),同时dataTask方法的歧义问题也会消除。
内容的提问来源于stack exchange,提问作者Louiza A
相关产品推荐
相关产品推荐

