2017-10-28 9 views
0

2点間の距離と時間を計算するclosureがありますが、クロージャの外に値の配列(directionsとjourneyTimes)を抽出する必要があります。スウィフト完了ハンドラ

私は、補完ハンドラが実行する方法はかなり確信していますが、それを実装する方法があまり明確ではありません。

マイコード:

するvar completionHandlers:[() - >ボイド] = []

@IBAction func calculateItinerary(_ sender: Any) { 

    // start calc 

    for index in 0...coordsOfCollective.count - 2 { 

     let sourceLocation = MKPlacemark(coordinate: coordsOfCollective[index]) 

     let destinationLocation = MKPlacemark(coordinate: coordsOfCollective[index + 1]) 

     let sourceMapItem = MKMapItem(placemark: sourceLocation) 
     let destinationMapItem = MKMapItem(placemark: destinationLocation) 

     let request = MKDirectionsRequest() 
     request.source = sourceMapItem 
     request.destination = destinationMapItem 

     request.transportType = .automobile 
     request.requestsAlternateRoutes = false 


     let directions = MKDirections(request: request) 

     directions.calculate { response, error in 
      if let route = response?.routes.first { 
       print("Distance: \(route.distance/1000) km, ETA: \(route.expectedTravelTime/60) mins") 

      self.distances.append(route.distance/1000) 
      self.journeyTimes.append(route.expectedTravelTime/60) 

       print(self.distances) 
       print(self.journeyTimes) 

       completionHandlers.append(?????) 

      } else { 
       print("Error!") 
      } 

     } 
    } 

print(completionHandlers) 

} 

directions.calculateは計算の宣言(completionHandler:@escaping MKDirectionsHandler)を有しているので、私それがエスケープクロージャであることがわかります。しかし、私はどのように距離を抽出し、それ以外のjourneyTimes配列を抽出するのか分かりません。印刷機能は現在値を生成していますが、他の場所からアクセスすることはできません。

何か助けていただければ幸いです。ありがとう。

completionHandlers[0]() 

をか、コードをより表現豊かにするために:

答えて

1
var completionHandlers: [() -> Void] = [] 

for i in 1...10 { 

    let handler = { 

     print(i) 

    } 

    completionHandlers.append(handler) 

} 

その後、あなたはハンドラを実行することができます

let handler = completionHandlers[0] 
handler() 

とハンドラのすべてを通過する:

completionHandlers.forEach { handler in 
    handler() 
} 

注意してください。配列にハンドラを格納しているときは、そのハンドラへの強い参照があります。閉鎖はあなたが閉鎖内に言及されているすべてのものへの強い参照を保持しますので、あなたがselfを参照するとき、それは、基準周期を簡単に作成できます:

let handler = { 
    self.myFunction() 
} 

あなたは自己への弱い参照してretaicnycleを避けることができます。

let handler = { [weak self] in 
    self?.myFunction() 
} 
+0

ありがとうMarcel。だから、私は基本的にハンドラとして計算を保存して、これをcompletionHandler配列に追加しますか? – mathleticolewis

+0

なぜあなたはクロージャの外で計算を処理したいですか? '.calculate {[weak self] response、error in ']を使って自分自身に強い参照をしないようにすることができます – Marcel

+0

計算の結果を別のView Controllerに渡そうとしています。だから私は、これを行う最善の方法は、結果の配列を作成し、その後にそれらを渡すことだと思った。 – mathleticolewis

関連する問題