谁能解释为什么我不能从这个方法返回一个值?

时间:2016-10-31 00:04:53

标签: ios swift geolocation cllocationmanager

我正在尝试使用快速地理编码来获取城市,但不知何故城市只有showup嵌套在方法中,当返回时变量为空,这是我正在使用的代码。

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

 }
}

3 个答案:

答案 0 :(得分:2)

正如here所指出的,你必须在方法中添加一个完成处理程序:

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
}

答案 1 :(得分:1)

你偶然发现了时间问题。 reverseGeocodeLocation是异步的,因此在完全评估闭包之前,方法会返回。

如果设置断点,您会看到

print("city second \(city)") //empty every time

行将在

之前触发
print(" city first \(self.city)") //contains a city

一个

答案 2 :(得分:1)

问题:

reverseGeocodeLocation是一种异步方法(它不会立即进行评估,并且需要时间来评估)。在reverseGeocodeLocation完成之前getLocation将完成。

解决方案:

修改getLocation以接受闭包作为参数。在reverseGeocodeLocation的完成处理程序内部调用该闭包并传递city

的值