2017-12-24 14 views
0

私は迅速な言語には新しく、私は解決できない問題があります。すぐに閉鎖内の変数に値を追加

私のアプリを実行した後、私は空の文字列の出力を得る:だからゼロ

を、私の質問は、閉鎖内の変数に値を追加する方法ですか?

私は閉鎖プリント(self.latLong)内の行を追加したときに、私は、座標の出力を得るが、私は後で私のコードと私ドンでその変数を操作する必要があるので、私は、変数の内部でその値を必要とするので「Tは、これが私のコードである閉鎖

内のすべての機能を書きたい:

import UIKit 
import CoreLocation 
import Firebase 

var latLong: String! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    findCordiante(adress: "Cupertino, California, U.S.") 
    print(latLong) 
} 

func findCordiante(adress:String){ 

    let geocoder = CLGeocoder() 
    geocoder.geocodeAddressString(adress) { 
     placemarks, error in 

     if (placemarks != nil){ 
      let placemark = placemarks?.first 
      let lat = placemark?.location?.coordinate.latitude 
      let lon = placemark?.location?.coordinate.longitude 

      self.latLong = String(describing: lat!) + "," + String(describing: lon!) 

     }else{ 
      //handle no adress 
      self.latLong = "" 
     } 
    } 

} 
+1

可能な複製(https://stackoverflow.com/questions/39880506/swift-closure-async-order-of-:たとえば、あなた自身の完了ハンドラパターンを採用実行) –

答えて

0

問題はgeocodeAddressString実行が非同期(すなわち、それはあまりにも長い間、彼らはすぐに戻り、要求が行われたときに、後でそのクロージャを呼び出すためにそれを書かれているかかります)ので、このプロパティはだった前によくviewDidLoadlatLongを印刷しているということです最終的にgeocodeAddressString補完ハンドラのクロージャで設定されます。

解決策は、独自のコードで非同期プログラミングパターンを採用することです。 [実行のスウィフト閉鎖非同期順序]の

override func viewDidLoad() { 
    super.viewDidLoad() 

    findCordiante(adress: "Cupertino, California, U.S.") { string in 
     // use `string` here ... 

     if let string = string { 
      self.latLong = string 
      print(string) 
     } else { 
      print("not found") 
     } 
    } 

    // ... but not here, because the above runs asynchronously and it has not yet been set 
} 

func findCordiante(adress:String, completionHandler: @escaping (String?) -> Void) { 
    let geocoder = CLGeocoder() 
    geocoder.geocodeAddressString(adress) { placemarks, error in 
     if let location = placemarks?.first?.location, location.horizontalAccuracy >= 0 { 
      completionHandler("\(location.coordinate.latitude), \(location.coordinate.longitude)") 
     } else { 
      completionHandler(nil) 
     } 
    } 
} 
0

LatLongブログのビューがロードされた直後print(latLong)が01の値の前に、呼び出されるためnilですが設定されています。 latLongを処理する関数を定義し、それをクロージャで呼び出すことができます。

import UIKit 
import CoreLocation 
import Firebase 

var latLong: String! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    findCordiante(adress: "Cupertino, California, U.S.") 
    print(latLong) 
} 

func findCordiante(adress:String){ 

    let geocoder = CLGeocoder() 
    geocoder.geocodeAddressString(adress) { 
     placemarks, error in 

     if (placemarks != nil){ 
      let placemark = placemarks?.first 
      let lat = placemark?.location?.coordinate.latitude 
      let lon = placemark?.location?.coordinate.longitude 

      self.latLong = String(describing: lat!) + "," + String(describing: lon!) 
      //Do something with latLong now 
      self.doSomething(withlatLong: self.latLong) 

     }else{ 
      //handle no adress 
      self.latLong = "" 
     } 
    } 

} 

private func doSomething(withlatLong latLong:String) { 
    //Do whatever you want with latLong 
    print(latLong) 
} 
+0

ありがとう、私は変数に座標を保存する必要があります。どうすればいいですか? – Sven

+0

「座標を変数に保存する」とはどういう意味ですか? 'self.latLong'はあなたのコードで' geocodeAddressString'が終わった後に設定されます。 'self.layLong'が設定されたときに通知を受けたい場合は、' didSet'または 'willSet'を使うことができます。 – luiyezheng

関連する問題