【问题标题】:Swift: Calling completion handler methods within in a for loopSwift:在 for 循环中调用完成处理程序方法
【发布时间】:2016-09-23 07:26:19
【问题描述】:

我想了解其中包含完成处理程序方法的 for 循环的行为。

请参阅下面的示例,我正在尝试获取 2 个地址的纬度/经度坐标。

let addressArray = ["1 Infinite Loop, Cupertino", "809, Harvard Ave, Sunnyvale, CA - 94087"]
var coordinatesArray = [CLLocationCoordinate2D]()

for i in 0 ..< addressArray.count {
    print(i)
    let address = addressArray[i]
    geocoder.geocodeAddressString(address, completionHandler: {(placemarks, error) -> Void in
        print("Address = \(address)");
        if let placemark = placemarks?.first {
            let coordinate = placemark.location?.coordinate
            self.coordinatesArray.append(coordinate!)
        }
    })
}

// Do something here after that that

输出是这样的

0
1
Address = 1 Infinite Loop, Cupertino

我想知道为什么代码中没有打印另一个地址。第二个 for 循环是否没有调用 geocodeAddressString 方法。假设 for 循环结束后应用程序执行还没有结束,我还做了很多其他的事情。

【问题讨论】:

  • 这真的是输出还是你输入的?最后一行不应该像Address = something
  • 您发布的代码未直接连接到输出,请使用从代码和控制台复制粘贴;你也打印address,这是什么?
  • 更新了代码和输出。
  • 您应该注意这种类型的异步循环请求中的竞争条件。英子提到here
  • 这就是我想知道的,异步循环请求的竞争条件行为。

标签: ios swift


【解决方案1】:

说明:

  • 有运行 N 次的 for 循环 (addressArray.count)。
  • 在每次迭代期间,都会发出地理编码请求。
  • 获取地点标记需要一些时间。
  • 这是一个异步方法,因此它不会阻塞执行(意味着循环继续运行并且不会等到地理请求完成)。
  • 完成特定迭代的地理编码请求后,将执行其完成处理程序。

问题:

  • 由于无法保证完成顺序,所以最好使用字典而不是数组。
  • 不要使用数组,因为完成的顺序可能不是连续的。
  • 例如,第一个请求可能在第二个请求完成后完成。

解决方案:

  • 对于给定的整数索引,coordinates[index] 将对应于addressArray[index]

代码(建议修复):

class Test {
    
    let geocoder = CLGeocoder()

    //Better use a dictionary instead of an array
    var coordinates = [Int: CLLocationCoordinate2D]()
    
    func f1() {
        
        for i in 0 ..< addressArray.count {
            print(i)
            let address = addressArray[i]
            
            geocoder.geocodeAddressString(address) {placemarks, error in
                print("Address = \(address)");
                if let placemark = placemarks?.first {
                    let coordinate = placemark.location?.coordinate
                    
                    self.coordinates[i] = coordinate
                }
            }
        }
    }
}

【讨论】:

  • 谢谢,我会用字典。我主要想知道异步循环请求的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-23
  • 2018-07-01
相关资源
最近更新 更多