有人可以解释为什么我不能 return 从这个方法中得到一个值吗?
can someone explain why i can't return a value from this method?
我正在尝试使用 swift 地理编码来获取城市,但不知何故,城市只显示嵌套在方法中,返回时变量为空,这是我正在使用的代码。
class {
var locationManager = CLLocationManager()
var longitude = CLLocationDegrees()
var latitude = CLLocationDegrees()
var city = ""
override func viewDidLoad() {
super.viewDidLoad()
setupLocation()
var x = getLocation()
print("\n\n x your city is: \(x)\n\n"); // 'x' is always empty
if x == "paris" {
print("\n\n your city is: \(x)\n\n"); // 'x' is always empty
}
}
func getLocation() -> String {
longitude = (locationManager.location?.coordinate.longitude)!
latitude = (locationManager.location?.coordinate.latitude)!
let location = CLLocation(latitude: latitude, longitude: longitude)
print(location)
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
print(location)
if error != nil {
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}
if placemarks!.count > 0 {
let pm = placemarks![0]
print("locality is \(pm.locality)")
self.city = pm.locality!
print(" city first \(self.city)") //contains a city
}
else {
print("Problem with the data received from geocoder")
}
})
print("city second \(city)") //empty every time
return city
}
}
您偶然发现了时间问题。 reverseGeocodeLocation
是异步的,所以闭包之前的方法 returns 是完全求值的。
如果您设置断点,您会看到
print("city second \(city)") //empty every time
行会在
之前触发
print(" city first \(self.city)") //contains a city
一个
问题:
reverseGeocodeLocation
是一种异步方法(它不会立即求值,需要时间求值)。在 reverseGeocodeLocation
完成之前 getLocation
将完成。
解决方案:
修改 getLocation
以接受闭包作为参数。在 reverseGeocodeLocation
的完成处理程序中调用闭包并传递 city
的值
正如所指出的 ,您必须向您的方法添加一个完成处理程序:
func getLocation(completion: @escaping (String) -> Void) {
longitude = (locationManager.location?.coordinate.longitude)!
latitude = (locationManager.location?.coordinate.latitude)!
let location = CLLocation(latitude: latitude, longitude: longitude)
print(location)
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
print(location)
if error != nil {
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}
if placemarks!.count > 0 {
let pm = placemarks![0]
print("locality is \(pm.locality)")
completion(pm.locality!)
}
else {
print("Problem with the data received from geocoder")
}
})
}
然后就这样做:
getLocation() {
locality in
self.city = locality
}
我正在尝试使用 swift 地理编码来获取城市,但不知何故,城市只显示嵌套在方法中,返回时变量为空,这是我正在使用的代码。
class {
var locationManager = CLLocationManager()
var longitude = CLLocationDegrees()
var latitude = CLLocationDegrees()
var city = ""
override func viewDidLoad() {
super.viewDidLoad()
setupLocation()
var x = getLocation()
print("\n\n x your city is: \(x)\n\n"); // 'x' is always empty
if x == "paris" {
print("\n\n your city is: \(x)\n\n"); // 'x' is always empty
}
}
func getLocation() -> String {
longitude = (locationManager.location?.coordinate.longitude)!
latitude = (locationManager.location?.coordinate.latitude)!
let location = CLLocation(latitude: latitude, longitude: longitude)
print(location)
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
print(location)
if error != nil {
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}
if placemarks!.count > 0 {
let pm = placemarks![0]
print("locality is \(pm.locality)")
self.city = pm.locality!
print(" city first \(self.city)") //contains a city
}
else {
print("Problem with the data received from geocoder")
}
})
print("city second \(city)") //empty every time
return city
}
}
您偶然发现了时间问题。 reverseGeocodeLocation
是异步的,所以闭包之前的方法 returns 是完全求值的。
如果您设置断点,您会看到
print("city second \(city)") //empty every time
行会在
之前触发print(" city first \(self.city)") //contains a city
一个
问题:
reverseGeocodeLocation
是一种异步方法(它不会立即求值,需要时间求值)。在 reverseGeocodeLocation
完成之前 getLocation
将完成。
解决方案:
修改 getLocation
以接受闭包作为参数。在 reverseGeocodeLocation
的完成处理程序中调用闭包并传递 city
正如所指出的
func getLocation(completion: @escaping (String) -> Void) {
longitude = (locationManager.location?.coordinate.longitude)!
latitude = (locationManager.location?.coordinate.latitude)!
let location = CLLocation(latitude: latitude, longitude: longitude)
print(location)
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
print(location)
if error != nil {
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}
if placemarks!.count > 0 {
let pm = placemarks![0]
print("locality is \(pm.locality)")
completion(pm.locality!)
}
else {
print("Problem with the data received from geocoder")
}
})
}
然后就这样做:
getLocation() {
locality in
self.city = locality
}