如何在 Swift 中等待异步调用?

How do I wait for an asynchronous call in Swift?

所以我最近在中断后回到 Swift & iOS,并且 运行 遇到了异步执行的问题。我正在使用 Giphy 的 iOS SDK 来为自己省去很多工作,但他们的文档几乎不存在,所以我不确定在调用 API 的函数中到底发生了什么.

我正在从静态对象的构造函数中调用包含以下代码的函数(我不认为这是问题所在,因为我还尝试从 Collection View 的 cellForItemAt 方法中调用它)。

我的问题是我的函数正在返回并且在 API 调用完成之前继续执行。我试过使用 DispatchQueue.main.async 并完全删除 Dispatch 和 DispatchGroups,但无济于事。一个有用的东西是信号量,但我想我记得读过它不是最佳实践?

任何提示都会很棒,我已经坚持这个 waaaaaay 太久了。非常感谢

GiphyCore.shared.gifByID(id) { (response, error) in
        if let media = response?.data {
            DispatchQueue.main.sync {
                print(media)
                ret = media
            }
        }
    }

return ret

My issue is that my function is returning and execution continues before the API call is finished.

这就是异步调用的全部意义所在。网络调用可能会花费任意时间,因此它会在后台启动请求并在完成时通知您。

不是从代码中返回值,而是获取回调参数并在知道 Giphy 调用已完成时调用它。或者使用承诺库。或者委托模式。

The one thing that worked was a semaphore, but I think I remember reading that it wasn't best practice?

不要这样做。它将阻止您的 UI 直到网络调用完成。由于您不知道这需要多长时间,因此您的 UI 将在未知的时间内无响应。用户会认为您的应用在低速连接时崩溃了。

您可以将它添加到方法中并使用完成处理程序,因此您不需要等待响应。你可以这样做:

func functionName(completion: @escaping (YOURDATATYPE) -> Void) {
    GiphyCore.shared.gifByID(id) { (response, error) in
        if let media = response?.data {
            completion(media)
            return
        }
    }
}

像这样调用你的方法

functionName() { response in
    DispatchQueue.main.async {
        // UPDATE the UI here
    }
}