我创建了一个类函数,它包含一个闭包,它将位置坐标反向地理编码为地址字符串。我最初把它写在一个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
}
}
答案 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
所以它将返回字符串,但它是空的,因为它是在异步函数完成之前返回的。