为啥 Swift 不更新闭包外的变量?

Posted

技术标签:

【中文标题】为啥 Swift 不更新闭包外的变量?【英文标题】:Why does Swift not update the variables outside the closure?为什么 Swift 不更新闭包外的变量? 【发布时间】:2014-10-16 01:12:59 【问题描述】:

这是我正在使用的代码——问题是返回的 CLLocationCoordinate2D 对象中的纬度和经度值都是 -1,它们的初始化值。我错过了什么?

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】:

作为@NateCook 回答的补充,重构代码的一种可能方法是:

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

获得位置后,您调用传递该位置的同一类的方法。由于处理程序闭包在主线程中执行,因此您可以安全地更新 UI 组件。

【讨论】:

【参考方案2】:

geocodeAddressString(:completionHandler:) 方法是异步的:

该方法将指定的位置数据异步提交给地理编码服务器并返回。您的完成处理程序块将在主线程上执行。发起正向地理编码请求后,请勿尝试发起另一个正向或反向地理编码请求。

所以它是在您创建 location 并从您的函数返回后执行的。您需要重构代码以异步处理。

【讨论】:

以上是关于为啥 Swift 不更新闭包外的变量?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Swift 的单数返回表达式中使用闭包简写变量必须详尽无遗?

为啥屏幕外的 UICollectionViewCells 不会更新?

将闭包更新到 Swift 3 - @escaping

为啥 Swift 闭包不捕获自我?

AFJSONRequestOperation 不更新块外的内容

如何在 Promise.then 中访问范围外的变量(类似于闭包)