为什么 .geocodeAddressString 不改变外部变量?
Why .geocodeAddressString doesn't change external variable?
我有一个外部变量chooseCoordinates,它的类型是CLLocationCoordinate2D。这个 var 需要保存来自 geocodeAddressString 闭包的坐标,但是,显然,它不会改变。
求教,如何让这个真正的闭包存储数据,这样我就能把它解析到另一个viewController
var chooseCoordinates = CLLocationCoordinate2D()
////////////
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(sender.text!, completionHandler: { (placemarks, error) -> Void in
if(error != nil) {
print("\(error)")
}
if let placemark = placemarks?.first {
let coordinates: CLLocationCoordinate2D = placemark.location!.coordinate
self.chooseCoordinates = coordinates
}
})
geocodeAddressString
异步运行(即即使方法 returns 立即执行,它的 completionHandler
闭包也可能稍后调用)。所以,你确定它没有改变,或者只是在你尝试使用 chooseCoordinates
时没有改变?您应该启动 UI 的任何更新或闭包(或 chooseCoordinates
的 didSet
)中的任何更新,而不是立即这样做。我们看不到您如何使用 chooseCoordinates
,因此很难说得更具体。
例如:
geocoder.geocodeAddressString(sender.text!) { placemarks, error in
if error != nil {
print(error!)
}
if let placemark = placemarks?.first {
let coordinates: CLLocationCoordinate2D = placemark.location!.coordinate
self.chooseCoordinates = coordinates
// call the method that uses `chooseCoordinates` here
}
}
// don't try to use `chooseCoordinates` here, as it hasn't been set yet.
或者,您可以自己使用 completionHandler
模式:
@IBAction func didEndEditingTextField(sender: UITextField) {
geocodeAddressString(sender.text!) { coordinate, error in
self.chooseCoordinates = coordinate
// trigger whatever the next step is here, or in the `didSet` of `chooseCoordinates`
}
// don't try to use `chooseCooordinates` here
}
var chooseCoordinates: CLLocationCoordinate2D? // you probably should make this optional
let geocoder = CLGeocoder()
/// Geocode string
///
/// - parameter string: The string to geocode.
/// - parameter completionHandler: The closure that is called asynchronously (i.e. later) when the geocoding is done.
func geocodeAddressString(string: String, completionHandler: (CLLocationCoordinate2D?, NSError?) -> ()) {
geocoder.geocodeAddressString(string) { placemarks, error in
if error != nil {
print(error!)
}
if let placemark = placemarks?.first {
completionHandler(placemark.location!.coordinate, error)
} else {
completionHandler(nil, error)
}
}
}
我有一个外部变量chooseCoordinates,它的类型是CLLocationCoordinate2D。这个 var 需要保存来自 geocodeAddressString 闭包的坐标,但是,显然,它不会改变。
求教,如何让这个真正的闭包存储数据,这样我就能把它解析到另一个viewController
var chooseCoordinates = CLLocationCoordinate2D()
////////////
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(sender.text!, completionHandler: { (placemarks, error) -> Void in
if(error != nil) {
print("\(error)")
}
if let placemark = placemarks?.first {
let coordinates: CLLocationCoordinate2D = placemark.location!.coordinate
self.chooseCoordinates = coordinates
}
})
geocodeAddressString
异步运行(即即使方法 returns 立即执行,它的 completionHandler
闭包也可能稍后调用)。所以,你确定它没有改变,或者只是在你尝试使用 chooseCoordinates
时没有改变?您应该启动 UI 的任何更新或闭包(或 chooseCoordinates
的 didSet
)中的任何更新,而不是立即这样做。我们看不到您如何使用 chooseCoordinates
,因此很难说得更具体。
例如:
geocoder.geocodeAddressString(sender.text!) { placemarks, error in
if error != nil {
print(error!)
}
if let placemark = placemarks?.first {
let coordinates: CLLocationCoordinate2D = placemark.location!.coordinate
self.chooseCoordinates = coordinates
// call the method that uses `chooseCoordinates` here
}
}
// don't try to use `chooseCoordinates` here, as it hasn't been set yet.
或者,您可以自己使用 completionHandler
模式:
@IBAction func didEndEditingTextField(sender: UITextField) {
geocodeAddressString(sender.text!) { coordinate, error in
self.chooseCoordinates = coordinate
// trigger whatever the next step is here, or in the `didSet` of `chooseCoordinates`
}
// don't try to use `chooseCooordinates` here
}
var chooseCoordinates: CLLocationCoordinate2D? // you probably should make this optional
let geocoder = CLGeocoder()
/// Geocode string
///
/// - parameter string: The string to geocode.
/// - parameter completionHandler: The closure that is called asynchronously (i.e. later) when the geocoding is done.
func geocodeAddressString(string: String, completionHandler: (CLLocationCoordinate2D?, NSError?) -> ()) {
geocoder.geocodeAddressString(string) { placemarks, error in
if error != nil {
print(error!)
}
if let placemark = placemarks?.first {
completionHandler(placemark.location!.coordinate, error)
} else {
completionHandler(nil, error)
}
}
}