2016-09-22 68 views
0

我試圖做的雨燕以下 - 試圖扭轉解碼地址列表中的陣列和打印他們的緯度/經度座標。我擁有的代碼如下。斯威夫特:異步調用的for循環

let addressArray = ["Address 1", "Address 2"] 
    var coordinatesArray = [CLLocationCoordinate2D]() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     createAddressList() 
     printAddressList() 
    } 

    func printAddressList() { 
     for i in 0 ..< addressArray.count { 
      print("Address = \(addressArray[i]) Coordinates = \(coordinatesArray[i].latitude),\(coordinatesArray[i].latitude)") 
    } 

    func createAddressList() { 
     for i in 0 ..< addressArray.count { 
      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!) 
       } 
      }) 
     } 
    } 
} 

該代碼只打印解碼的第一個地址,然後什麼也沒有發生。

我有這個像下面的一個,這是對printAddressList呼叫從viewDidLoad方法移動這樣

func createAddressList() { 
    if count < self.addressArray.count { 
     let address = addressArray[count] 
     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!) 
      } 
      print("Count = \(self.count)") 
      self.count += 1 
      self.createAddressList() 
     }) 
    } else { 
     printAddressList() 
    } 
} 

修復即使後者解決方案工作,我看到它是不乾淨的,會喜歡在使代碼易讀和清潔的同時知道正確的方式來做到這一點。

回答

3

如何使用這種結構?

let workGroup = dispatch_group_create() 

for i in 0..<addressArray.count { 

    dispatch_group_enter(workGroup) 

    performGeoCoding({ successCallback : 

      dispatch_group_leave(workGroup) 

    }) 
} 

dispatch_group_notify(workGroup, dispatch_get_main_queue()){ 
    successCallback() 
    printAddressList()      
} 

關於dispatch_group here有非常好的教程。

+0

首先感謝您的建議。我從您提供的鏈接中瞭解了更多關於派遣組的信息。但我無法理解你給出的解決方案。我的問題是在for循環中有地理編碼方法。到第一個地址被解碼時,for循環完成第二次迭代。問題是爲什麼我沒有看到解碼的第二個地址(我的情況是地理編碼中的打印語句)。我應該使用while循環而不是for循環。 – sysuser

+0

我認爲使用for循環或while循環無關緊要。就像你在標題中提到的那樣,它是異步調用,它不保證在調用printAddressList()之前結束處理程序的結果會返回。例如,當您的第一個地理編碼請求返回時,您的程序已經通過地址數組循環,然後可能執行printAddressList函數,該函數不會輸出正確的值。這就是爲什麼我認爲您需要使用dispatch_group,以便您可以等待直到從完成處理程序收集所有需要的結果。 – woogii

+0

確實,帶通知的調度處理程序有效。 – sysuser