2016-09-22 18 views
0

私はすぐに次のことをしようとしています - 配列内のアドレスのリストを逆デコードして緯度/経度座標を表示しようとしています。私が持っているコードは以下の通りです。Swift: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!) 
       } 
      }) 
     } 
    } 
} 

コードはデコードされた最初のアドレスのみを出力し、何も起こりません。

は、私は希望、後者のソリューションは、作品にもかかわらず、私はそれはきれいではないことがわかり、この

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() 
    } 
} 

ようviewDidLoadメソッドからprintAddressList呼び出しを移動することです1、以下のようなこのための修正を持っていますコードを読みやすくきれいにしながらこれを行う正しい方法を知りたいのです。

答えて

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ループは2回目の反復を完了しました。問題は、なぜ私は2番目のアドレスが全くデコードされていない(私の場合はジオコード内のprintステートメント)が見えないかということです。 forループの代わりにwhileループを使用しますか? – sysuser

+0

forループとwhileループのどちらを使用するかは関係ありません。タイトルで述べたように、printAddressList()が呼び出される前に完了ハンドラの結果が返されることを保証しない非同期呼び出しです。たとえば、最初のジオコード要求が返ってくるまでに、プログラムはすでにアドレス配列をループしていて、正しい値を出力しないprintAddressList関数を実行している可能性があります。そのため、完了ハンドラから必要なすべての結果を収集するまで待つことができるように、dispatch_groupを使用する必要があると思います。 – woogii

+0

trueの場合、通知付きディスパッチハンドラが機能します。 – sysuser

関連する問題