如何在 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
}
}
所以我最近在中断后回到 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
}
}