繁体   English   中英

如何正确地等到功能迅速完成?

[英]How to properly wait until function has finished doing in 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
    }
})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM