如何在闭包

时间:2016-05-08 14:03:56

标签: ios swift pointers inout

所以我的问题是: 我正在尝试实现CLGeoCoder的扩展,以便能够从CLLocation获取城市名称,但是当我尝试在reverseGeocodeLocation的completionhandler中设置inout城市名称字符串时我遇到了问题

以下是我的扩展程序的代码:

extension CLGeocoder {

  func findCityName(location:CLLocation, inout cityName:String) -> Void{
      self.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in

        // Place details
        var placeMark: CLPlacemark!
        placeMark = placemarks?[0]

        // Address dictionary
        print(placeMark.addressDictionary)



        // City
        if let city = placeMark.addressDictionary!["City"] as? String {
            cityName = city
        } 
      })
  } 
} 

此扩展的目标是通过引用此函数来设置带有城市名称的字符串。

一个例子是:

var cityName = ""
let location:CLLocation(latitude: 1, longitude: 1)
let geocoder: CLGeocoder()
geocoder.findCityName(location, &cityName)

///Later on in the process I would want to be able to use cityName for different purposes in my code 

我面临的问题是,在completionHandler中设置cityName引用后,cityName的值在完成处理程序之外保持为空。

我是swift的新手,所以我可能会错过指针上的内容或如何使用它们,但我理解inout可以从函数内部或闭包/完成处理程序中更改变量的值

提前感谢您提供有关我正面临的这个问题的任何信息。

马丁

1 个答案:

答案 0 :(得分:0)

当您的findCityName函数退出时,cityName变量尚未更改。 reverseGeocodeLocation 的完成处理程序将最终更新原始cityName的 copy 变量,而不是最初传递给该函数的变量。完成处理程序不会立即执行:它们执行。如果它们立即执行,函数可以返回结果而不是使用完成处理程序,对吧?

现在,我同意你的观点,这很奇怪。但奇怪的是,Swift不会更新你的inout变量。奇怪的是Swift让这个程序编译。因为它没有任何意义。跟我来:

想象一下以下功能:

func f() {
    var cityName: String = ""
    findCityName(location, &cityName)
}

当你调用它时,当最终执行reverseGeocodeLocation的完成处理程序时,你在中传递的cityName变量不再存在。 f()函数早已退出,局部变量cityName已经消失。

知道了吗?即使希望inout变量可以更新也毫无意义。

因此。现在,您必须重构代码。也许使用完成处理程序。