如何访问块外的变量? [复制]

Posted

技术标签:

【中文标题】如何访问块外的变量? [复制]【英文标题】:How can I access a variable outside block? [duplicate] 【发布时间】:2015-02-18 13:45:57 【问题描述】:

以下代码无法正常工作。

  func convertToStreet(location:CLLocationCoordinate2D) -> CLPlacemark 

    var tempLocation = CLLocation(latitude: location.latitude, longitude: location.longitude)

    var temPlacemark:CLPlacemark?

    CLGeocoder().reverseGeocodeLocation(tempLocation, completionHandler: (placemarks, error) in

        temPlacemark = (placemarks[0] as CLPlacemark)
        println(temPlacemark!.thoroughfare)

    )

    return temPlacemark!

完成处理程序中的 Println 可以正常工作,但 temPlacemark 的值在代码末尾为 nil。为什么会这样?非常感谢您。

【问题讨论】:

发生这种情况是因为在返回时,它仍在处理它。如果您让线程等待一定的时间,您将获得正确的值。此外,如果您将断点放在完成处理程序内部和外部,您将看到外部部分首先执行。 【参考方案1】:

这是因为 completionHandler 是异步调用的。为此,您应该在自定义函数中有一个回调块,以便在您从 CLGeocoder 获取值后返回该值。

类似这样的:

func convertToStreet(coordinate: CLLocationCoordinate2D, completionHandler: (placemark: CLPlacemark!, error: NSError!) -> Void) 
    let tempLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)

    CLGeocoder().reverseGeocodeLocation(tempLocation)  placemarks, error in
        completionHandler(placemark: placemarks?.first as CLPlacemark?, error: error)
    

然后你可以这样称呼它:

convertToStreet(location.coordinate)  placemark, error in
    if placemark != nil 
        // use `placemark` here
        println(placemark.thoroughfare)
     else 
        println(error)
    


// but don't use `placemark` here

【讨论】:

谢谢你,@Rob!我只是想对我提出的解决方案给出一个总体概念。但我绝对不应该写那个例子,因为我现在知道的语言是 Objective-C,而不是 Swift。 随意吧 ;) @Rob【参考方案2】:

你的代码的问题是代码块:

temPlacemark = (placemarks[0] as CLPlacemark)
println(temPlacemark!.thoroughfare)

稍后会执行。

意味着当前的return 语句将始终返回一个未初始化的值。 如果你想在你的块中初始化这个var,你应该让它成为你对象的property

【讨论】:

以上是关于如何访问块外的变量? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

AFJSONRequestOperation 不更新块外的内容

处理Scala Async和Future变量的异常,在try块外访问变量名时出错

ES6第一部分

如何在 Promise.then 中访问范围外的变量(类似于闭包)

无法访问异步函数外的变量[重复]

在 Firebase 块外使用变量