Swift 4报错:无效的抛出函数转换问题及代码求助
解决Swift 4中「Invalid conversion from throwing function」错误
嘿,我来帮你搞定这个报错!这个错误主要是因为你的代码里闭包签名不匹配,再加上可能存在未处理的抛出操作导致的,咱们一步步来修复:
问题根源
- 闭包签名不兼容:
URLSession.dataTask的完成闭包要求接收三个参数(Data?,URLResponse?,Error?),但你定义的Odpowiedz类型只接受两个参数,直接传入会导致类型不匹配。 - 未处理的抛出操作:如果后续你在闭包里做了比如JSON解析这类可能抛出错误的操作,但你的
Odpowiedz回调并没有声明支持抛出,Swift就会报错说“无法从抛出函数转换”。
修复代码
先把你的Connect结构体代码修正成下面这样,我加了详细的注释:
public struct Connect { let adresSerwera = "http://test.nazwa.pl/" typealias Odpowiedz = (Data?, Error?) -> Void func getJsonFromServer(parametry: String, wynikRequesta: @escaping Odpowiedz) { // 1. 构造URL,失败时主动回调错误 guard let url = URL(string: self.adresSerwera + "kartyEndpoint.qbpage" + parametry) else { let invalidURLError = NSError(domain: "ConnectError", code: 101, userInfo: [NSLocalizedDescriptionKey: "Nieprawidłowy adres URL"]) wynikRequesta(nil, invalidURLError) return } // 2. 适配URLSession的闭包签名,处理所有参数 URLSession.shared.dataTask(with: url) { (data, response, error) in // 优先处理请求错误 if let requestError = error { wynikRequesta(nil, requestError) return } // 可选:验证HTTP响应状态码(确保请求成功) if let httpResponse = response as? HTTPURLResponse, !(200...299).contains(httpResponse.statusCode) { let statusError = NSError(domain: "ConnectError", code: httpResponse.statusCode, userInfo: [NSLocalizedDescriptionKey: "Błąd HTTP: \(httpResponse.statusCode)"]) wynikRequesta(nil, statusError) return } // 3. 把数据传递给自定义回调 wynikRequesta(data, nil) }.resume() // 别忘了调用resume()!不然请求根本不会执行 } }
如果需要处理可抛出操作(比如JSON解析)
要是你之后要在闭包里做JSON解析这类可能抛出错误的操作,一定要用do-catch捕获错误,不能直接throw,因为URLSession的闭包不允许抛出错误。示例如下:
// 在dataTask的闭包内添加JSON解析逻辑 URLSession.shared.dataTask(with: url) { (data, response, error) in if let requestError = error { wynikRequesta(nil, requestError) return } guard let responseData = data else { let noDataError = NSError(domain: "ConnectError", code: 100, userInfo: [NSLocalizedDescriptionKey: "Brak danych od serwera"]) wynikRequesta(nil, noDataError) return } do { // 尝试解析JSON,这里会抛出错误 let jsonObject = try JSONSerialization.jsonObject(with: responseData, options: []) // 这里可以处理解析后的JSON数据 print("Otrzymano JSON: \(jsonObject)") wynikRequesta(responseData, nil) } catch let parseError { // 捕获解析错误,传递给回调 wynikRequesta(nil, parseError) } }.resume()
几个关键提醒
- 一定要调用
resume()启动网络任务,很多新手会漏掉这一步,导致请求没反应。 - URL构造失败时别直接
return,要主动给调用者回调错误,避免调用者一直等待。 - 所有可能抛出错误的操作,都要用
do-catch包裹,不让错误逃逸出闭包。
内容的提问来源于stack exchange,提问作者Łukasz Betta
相关产品推荐
相关产品推荐

