【问题标题】:Swift variable declared outside closure is updated inside closure but when accessed outside closure it returns the default value?在闭包外部声明的 Swift 变量在闭包内部更新,但是当在闭包外部访问时它返回默认值?
【发布时间】:2020-04-25 16:42:20
【问题描述】:

所以我调用的函数应该只返回输入地址的经度。我将它附加在这里,以便您查看它,然后我将在代码之后对其进行评论:

func getLongitude(address: String) -> Double {
    var longitude: Double = 0.0
    let geocoder = CLGeocoder()
    geocoder.geocodeAddressString(address) {
        placemarks, error in 
        let placemark = placemarks?.first
        longitude = placemark?.location?.coordinate.longitude ?? 0.0
        print("The testing longitude is \(longitude)")
    }
    return longitude
}

如您所见,我用默认值 0.0 声明了经度变量。在函数内部的闭包中,我更新了经度。 print 语句确认在该函数的闭包中更新了经度。当在此闭包之外使用 return 语句访问经度时,它会再次返回 0.0 (我相信经度的值在闭包之外没有发生变化,但我不知道如何解决这个问题)。任何帮助将不胜感激!

【问题讨论】:

  • 嗨,马特,我在这里遇到了一个小问题。所以 getLongitude 函数必须返回一个双精度值。但是我使用的内置函数 gecodeAddressString 使用了一个返回类型为 void 的回调函数。 geocodeAddressString 回调函数的返回类型为 void 时,如何返回?
  • 重读文章!你不能返回双倍。您需要重写您的getLongitude,以便 it 采用 a 完成处理程序 采用双精度。在 geocodeAddressString 完成处理程序中,您调用该完成处理程序,并将其传递给 double。

标签: swift closures geocode


【解决方案1】:

请使用制表符使您的代码更易于阅读。

无论如何geocoder.geocodeAddressString(address) 是一个带有回调的方法,在这个回调方法中你有地标。您的返回不会等待该回调,因为计算坐标需要时间,因此它返回您在开始时设置的 0.0。


编辑:比您在评论中提出的更长的版本:

CLGeocoder() 的函数geocodeAddressString 实际上有两个参数:地址和所谓的回调。回调只是任务(在本例中是计算地标)完成时调用的方法。 Swift 允许你用“swifty”语法编写回调,但实际上它看起来像

geocoder.geocodeAddressString(address, callAfterFinishGeocoding)

func callAfterFinishGeocoding(_ placemark: Placemark) {
   // do stuff with placemark
}

如您所见,我们将地理编码函数传递给另一个函数,以便在完成时调用。 callAfterFinishGeocoding 的参数在geocodeAddressString 中定义。它看起来类似于:

callback: @escaping (_ placeMark: Placemark) -> Void

这意味着回调应该是一个接受地标并返回 Void 的函数。跳转到方法的定义,看看它想要什么样的函数作为参数。

还可以在这里阅读更多内容:https://stackoverflow.com/a/46245943/13087977

【讨论】:

  • 所以我相信我可以使用 Andrey 的代码......然后当我调用 getLongitude 函数时,它看起来像 getLongitude(address: addressString, completion: (doubleBeingPassedIn: Double) - > Double { return doubleBeingPassedIn },对吗?或者当调用 getLongitude 函数时应该完成的参数是完全错误的?更新:我试图将该值传递给完成并得到错误 Expected type after '- >'和使用未解析的标识符'valueBeingPassedIn'
  • 另外我很抱歉我的 Swift 太差了,我这辈子从来没有用过任何语言的回调函数
  • 是的,安德烈斯代码是正确的。调用 getLongitude() 并将其传递给您要使用经度执行的函数。您传递的函数必须接受 Double 并返回 Void。
  • 别心疼,我一开始也没明白。一旦它“点击”你就会得到它
  • 您不能返回 Double(或其他任何东西)。这永远不会起作用,因为您的操作是异步的并且您不能等待“返回”。你应该重新考虑你的结构。返回后要执行的代码也可以直接在回调中执行。
【解决方案2】:

闭包是异步执行的,即在 return 语句运行之后。将您的功能更改为

func getLongitude(address: String, completion: @escaping (Double)->Void)
 {
     var longitude: Double = 0.0
     let geocoder = CLGeocoder()

    geocoder.geocodeAddressString(address)
    {
        placemarks, error in
        let placemark = placemarks?.first
        longitude = placemark?.location?.coordinate.longitude ?? 0.0
        print("The testing longitude is \(longitude)")

        completion(longitude)
    }
 }

【讨论】:

  • 嗨,安德烈,我不是对您的评论投反对票的人。不过,当谈到参数中的完成处理程序时,我有点困惑(我相信这就是你正在做的)。有没有参考资料可以让我了解更多关于他的信息?我也很不确定如何调用这个函数(即我为“完成”参数提供的参数是什么)。非常感谢您的宝贵时间!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-18
  • 1970-01-01
  • 2012-08-31
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
  • 2011-04-11
相关资源
最近更新 更多