2017-12-24 5 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

문제는 너무 viewDidLoad이 부동산이었다 훨씬 이전 latLong를 인쇄하고, 비동기 geocodeAddressString 실행 (즉이 너무 오래 걸립니다 그들이 그것을 즉시 반환하고 요청이 완료 이후의 폐쇄, 전화를 작성했습니다)이다 결국 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은 nilprint(latLong) 때문에보기가로드 된 후에 01의 값 앞에 즉시 호출이 설정되었습니다. 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