Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 从内部DispatchQueue Swift返回_Ios_Swift_Asynchronous - Fatal编程技术网

Ios 从内部DispatchQueue Swift返回

Ios 从内部DispatchQueue Swift返回,ios,swift,asynchronous,Ios,Swift,Asynchronous,我正在构建一个函数,它接受CLLocation参数并返回我自己定义的DarkSkyResponse类型的天气预报 public func getForecast(at location: CLLocation) -> DarkSkyResponse { let request = DarkSkyRequest(key: "KEYGOESHERE") let point = DarkSkyRequest.Point(location.coordinate.latitude,

我正在构建一个函数,它接受
CLLocation
参数并返回我自己定义的
DarkSkyResponse
类型的天气预报

public func getForecast(at location: CLLocation) -> DarkSkyResponse {
    let request = DarkSkyRequest(key: "KEYGOESHERE")
    let point = DarkSkyRequest.Point(location.coordinate.latitude, location.coordinate.longitude)

    guard let url = request.buildURL(point: point) else {
        preconditionFailure("Failed to construct URL")
    }

    let task = URLSession.shared.dataTask(with: url) {
        data, response, error in

        DispatchQueue.main.async {
            guard let data = data else {
                fatalError("No Data Recieved")
            }
            guard let forecast = DarkSkyResponse(data: data) else {
                fatalError("Decoding Failed")
            }
            return forecast
        }
    }
    task.resume()
}
一切都很正常,我只想返回DispatchQueue中的
forecast
变量。当我尝试执行此操作时,遇到以下错误:
无效函数中意外的非无效返回值
我相信这是因为我在调度队列中返回

为了尝试解决这个问题,我将数据任务和解码过程移动到它自己的具有完成处理程序的函数中。当我调用函数时,我只设置了闭包以返回输出,如下所示:

public func getForecast(at location: CLLocation) -> DarkSkyResponse {
    let request = DarkSkyRequest(key: "KEYGOESHERE")
    let point = DarkSkyRequest.Point(location.coordinate.latitude, location.coordinate.longitude)

    guard let url = request.buildURL(point: point) else {
        preconditionFailure("Failed to construct URL")
    }

    func getDataAndDecode(from url: URL, completionBlock: @escaping (DarkSkyResponse) -> Void) -> Void {
        let task = URLSession.shared.dataTask(with: url) {
            data, response, error in

            DispatchQueue.main.async {
                guard let data = data else {
                    fatalError("No Data Recieved")
                }
                guard let forecast = DarkSkyResponse(data: data) else {
                    fatalError("Decoding Failed")
                }
                completionBlock(forecast)
            }
        }
        task.resume()
    }

    getDataAndDecode(from: url) { (output) in
        return output
    }
}

现在我收到一条警告:
类型为'DarkSkyResponse'的表达式未使用
。我这样做是正确的,还是有更优雅的方式返回我想要的值?

目前,swift还不支持异步等待样式(类似于javascript),这意味着您不能直接从异步操作返回。 最好将callback(completionBlock)参数放在getForecast方法中。如果回调也能处理错误情况(例如onSuccess和onError),那就更好了。不要忘记将getForecast方法设置为void方法

所以会是这样的:


func getForecast(at location: CLLocation, onSuccess: (DarkSkyResponse) -> (), onError: (Error) -> ()) {

...
}


或者可以考虑使用RXSWIFT,利用继电器操作员得到结果。