代码在 swift 中完成 运行 之前的函数 returns

Function returns before code finishes running in swift

我创建了一个 class 函数,其中包含一个将位置坐标反向地理编码为地址字符串的闭包。我最初是用 viewcontroller 编写的,但我需要 运行 将这段代码写在几个地方。

我的问题是class函数returns闭包前的字符串运行s,所以返回的字符串是空的。我有什么方法可以解决这个问题?还有比使用 class 函数更好的方法来组织我的代码吗?

import CoreLocation
class LocationUtil: CLLocation {
    class func getLocationAddress(location:CLLocation?) -> NSString {
        var geocoder = CLGeocoder()
        var addressString : String = ""

        if location != nil {
            geocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error)->Void in
                var placemark:CLPlacemark!

                if error == nil && placemarks.count > 0 {
                    placemark = placemarks[0] as CLPlacemark

                    if placemark.subThoroughfare != nil {
                        addressString = placemark.subThoroughfare + " "
                    }
                    if placemark.thoroughfare != nil {
                        addressString = addressString + placemark.thoroughfare + ", "
                    }
                    if placemark.locality != nil {
                        addressString = addressString + placemark.locality + ", "
                    }
                    if placemark.administrativeArea != nil {
                        addressString = addressString + placemark.administrativeArea + " "
                    }
                    if placemark.postalCode != nil {
                        addressString = addressString + placemark.postalCode + " "
                    }
                    if placemark.country != nil {
                        addressString = addressString + placemark.country
                    }

                }
                println("Address in closure: \(addressString)") //prints addresss
            })
        }
        println("Address out of closure: \(addressString)") // doesn't print address
        return addressString //this returns nothing
    }
}

你应该 return 你的

里面的 completionHandler
geocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error)->Void in

函数结束时会调用completionHandler。为此,您还应该异步创建自己的函数 return。

这是必需的,因为您的 reverseGeocodeLocation 函数是 运行 异步的。您的主线程将继续 运行 您的 getLocationAddress 因此它将 return 字符串但它是空的,因为它是 return 在异步函数完成之前编辑的。

geocoder.reverseGeocodeLocation 异步运行 并仅在 完成后调用 completionHandler .

因此,获得 return 值显然不是一种选择。相反,接受闭包作为 input/argument 用于 class 函数

class func getLocationAddress(location: CLLocation, getLocCompletionHandler : (addressString : String?, error : NSError?) -> Void) {

       geocoder.reverseGeocodeLocation(location, completionHandler: {(placemarks, error)->Void in
            //Your current code
            //...
            //...
            println("Address: \(addressString)")
            //Instead of returning the address string, call the 'getLocCompletionHandler'
            getLocCompletionHandler(addressString: addressString, error: error)

        })
}

并且当您调用此函数时,不要使用 return 值,而是等待闭包被调用:

LocationUtil.getLocationAddress(currentLocation, completionHandler: { (addressObject, error) -> Void in
    println("Address: \(addressString)")
    //OR handle the error appropriately
}

继续阅读 closures 以更好地理解这个概念。

就代码组织而言,class 函数在这种情况下是一个不错的选择。