Why does Swift not update the variables outside the closure?

一曲冷凌霜 提交于 2020-01-15 12:26:26

问题


Here's the code I'm using -- Problem is that the value of latitude and longitude in the returned CLLocationCoordinate2D object are both -1, their initialized values. What am I missing?

func getLocationInfoForAddress(shop: store) -> CLLocationCoordinate2D {

    var address = getAddressInOneLine(shop)
    var latitude: CLLocationDegrees = -1
    var longitude: CLLocationDegrees = -1

    var geocoder = CLGeocoder()
    geocoder.geocodeAddressString(address, {(placemarks: [AnyObject]!, error: NSError!) -> Void in
        if let placemark = placemarks?[0] as? CLPlacemark {
            latitude = placemark.location.coordinate.latitude
            longitude = placemark.location.coordinate.longitude
        }
    })

    var location: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: latitude,longitude: longitude)
    return location
}

回答1:


As a complement to @NateCook's answer, one possible way to refactor your code is:

func getLocationInfoForAddress(shop: store) {
    var address = getAddressInOneLine(shop)

    var geocoder = CLGeocoder()
    geocoder.geocodeAddressString(address, {(placemarks: [AnyObject]!, error: NSError!) -> Void in
        if let placemark = placemarks?[0] as? CLPlacemark {
            var latitude = placemark.location.coordinate.latitude
            var longitude = placemark.location.coordinate.longitude

            var location: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: latitude,longitude: longitude)
            self.didReceiveGeocodeAddress(location)
        }
    })
}

func didReceiveGeocodeAddress(location: CLLocationCoordinate2D) {
    // do something
}

When the location is obtained, you invoke a method of the same class passing the location. Since the handler closure is executed in the main thread, you can safely update UI components.




回答2:


The geocodeAddressString(:completionHandler:) method is asynchronous:

This method submits the specified location data to the geocoding server asynchronously and returns. Your completion handler block will be executed on the main thread. After initiating a forward-geocoding request, do not attempt to initiate another forward- or reverse-geocoding request.

So it is being executed after you've created location and returned it from your function. You'll need to refactor your code to handle this asynchronously.



来源:https://stackoverflow.com/questions/26394699/why-does-swift-not-update-the-variables-outside-the-closure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!