swift - 如何正确等待函数快速完成?
问题描述
我现在尝试了很多东西,但似乎没有一个有效。
我有一个 for 循环,它解析一些数据并将坐标转换为 ZIP 字符串:
for i in 0 ... results.count - 1
{
result = results[i]
self.coordinateToString(lat: result.lat, long: result.long, completion: { (place) in
someCell.label.text = place
})
}
func coordinateToString(lat: Double, long: Double, completion: @escaping (String) -> ()) {
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: lat, longitude: long)
var ret = ""
geoCoder.reverseGeocodeLocation(location, completionHandler:
{
placemarks, error -> Void in
guard let placeMark = placemarks?.first else { return }
if let zip = placeMark.postalCode, let town = placeMark.subAdministrativeArea
{
let toAppend = "\(zip)" + " \(town)"
ret = toAppend
}
})
DispatchQueue.main.async {
completion(ret)
}
}
但是我从来没有设法在单元格中显示正确的位置,它总是显示空白空间,因为它不等待完成处理程序完成转换。我在这里做错了什么?
解决方案
发生这种情况是因为reverseGeocodeLocation
立即返回并且其完成处理程序随后运行。这意味着ret
当它被放入主队列时,它可能是空的。您应该从回调中分派到 main ,如下所示:
func coordinateToString(lat: Double, long: Double, completion: @escaping (String) -> ()) {
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: lat, longitude: long)
var ret = ""
geoCoder.reverseGeocodeLocation(location, completionHandler:
{
placemarks, error -> Void in
guard let placeMark = placemarks?.first else { return }
if let zip = placeMark.postalCode, let town = placeMark.subAdministrativeArea
{
let toAppend = "\(zip)" + " \(town)"
ret = toAppend
DispatchQueue.main.async {
completion(ret)
}
}
})
当然,在这种情况下,您需要相应地处理错误情况。更好的是,使用defer
,无论发生什么,都会调用完成:
func coordinateToString(lat: Double, long: Double, completion: @escaping (String) -> ()) {
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: lat, longitude: long)
var ret = ""
geoCoder.reverseGeocodeLocation(location, completionHandler:
{
defer {
DispatchQueue.main.async {
completion(ret)
}
}
placemarks, error -> Void in
guard let placeMark = placemarks?.first else { return }
if let zip = placeMark.postalCode, let town = placeMark.subAdministrativeArea
{
let toAppend = "\(zip)" + " \(town)"
ret = toAppend
}
})
推荐阅读
- xamarin.android - Autodesk Forge Viewer 在 android 中加载时间延迟,使用 Xamarin 时性能变慢,Forge Offline Viewer
- javascript - 让 div 在滚动时消失
- machine-learning - 我在哪里可以找到 Andrew Ng 的 DL 专业化的练习?
- python - 如何在python中启动计时器并将其重置?
- oracle - Oracle 11g 中对 CHECKSUM 的支持
- sql - 如何获取动态列数?
- vue.js - 如何获取类星体中选择选项的实际数据?
- javascript - 如何在结果中获取 XMLHttpRequest 的属性值
- java - 创建带有自定义标头请求的 Rest API
- postgresql - 使用 Kubernetes configMap 更改 Postgres 配置