函数在代码完成在swift中运行之前返回

时间:2015-04-21 19:25:23

标签: ios swift asynchronous closures

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

我的问题是类函数在闭包运行之前返回字符串,因此返回的字符串为空。有什么办法可以解决这个问题?是否有更好的方法来组织我的代码而不是使用类函数?

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
    }
}

2 个答案:

答案 0 :(得分:9)

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

因此,获得返回值显然不是一种选择。相反,接受闭包作为类函数的输入/参数

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)

        })
}

当你调用这个函数时,不要使用返回值,而是等待调用闭包:

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

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

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

答案 1 :(得分:4)

您应该返回

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

函数完成后将调用completionHandler。为此,您还应该异步返回自己的函数。

这是必需的,因为您的reverseGeocodeLocation函数是异步运行的。你的主线程将继续运行你的getLocationAddress所以它将返回字符串,但它是空的,因为它是在异步函数完成之前返回的。