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

Swift 4报错:无效的抛出函数转换问题及代码求助

解决Swift 4中「Invalid conversion from throwing function」错误

嘿,我来帮你搞定这个报错!这个错误主要是因为你的代码里闭包签名不匹配,再加上可能存在未处理的抛出操作导致的,咱们一步步来修复:

问题根源

  1. 闭包签名不兼容:URLSession.dataTask的完成闭包要求接收三个参数(Data?, URLResponse?, Error?),但你定义的Odpowiedz类型只接受两个参数,直接传入会导致类型不匹配。
  2. 未处理的抛出操作:如果后续你在闭包里做了比如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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 07:05:28