Swift 递归闭包栈溢出 bug

标签 swift recursion closures stack-overflow

更新:需要注意的是,下面的问题是学术性质的,核心位置的使用,或者位置数据的轮询与问题无关——正确的方法总是通过核心位置委托(delegate)方法。我最初的问题最终归结为:“无限递归是否可能在 swift 中实现?(或尾递归)”。答案是否定的。这就是由于堆栈空间耗尽而导致我的错误的原因。

原问题: 我在使用通过闭包传递值的递归函数时遇到问题。我是一名长期的 Objective-C 开发人员,但使用 Swift 编程的时间并不长,所以我可能遗漏了一些明显的东西。这是函数以及我如何调用它:

public func getLocation(completion: @escaping (CLLocationCoordinate2D?) -> ())
{
    completion(self.currentLocation)
    weak var weakSelf = self
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        weakSelf?.getLocation(completion: {location in
            completion(weakSelf?.currentLocation)
        })
    }
}

LocationManager.shared.getLocation(completion: {location in
        if(location != nil)
        {
            weakSelf?.lonLabel.text = "Lat: " + location!.latitude.description
            weakSelf?.latLabel.text = "Lon: " + location!.longitude.description
        }
    })

运行一段时间后得到的bug(描述Thread 1: EXC_BAD_ACCESS (code=2, address=0x16f1b7fd0))是这样的:

enter image description here

我想要完成的是将一个自动更新的位置值传递给位置管理器对象。我在想另一种方法是使用 performSelector withObject afterDelay 但此时,我只是想知道为什么会崩溃?

最佳答案

getLocation(completion:) 调用 getLocation(completion:) 会导致堆栈溢出,后者会调用 getLocation(completion:), ... 直到堆栈空间用完。

您可以改用 DispatchSourceTimer:

import Dispatch

let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.main)
timer.schedule(deadline: .now(), repeating: .seconds(5), leeway: .milliseconds(100))

timer.setEventHandler { [weak self] in
    guard let strongSelf = self,
          let location = LocationManager.shared.currentLocation else { return }
    strongSelf.lonLabel.text = "Lat: \(location.latitude)"
    strongSelf.latLabel.text = "Lon: \(location.longitude)"
}

timer.resume()

但是整个轮询方法没有任何意义。您的位置代表已被告知位置更改。然后您可以更改标签。

关于Swift 递归闭包栈溢出 bug,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48193936/

相关文章:

caching - "Expected type parameter, found reference to type parameter"实现通用缓存结构时

types - 是否可以将闭包分配给 impl Fn() 类型的变量?

string - 如何在 Swift 中连接字符串?

swift - Realm 过滤器并不总能找到数据?

c++ - 在并行桶排序中使用递归基数排序

c - 返回大于数组第一个索引的数字数量的递归函数

java - 在递归计算幂时我不理解我的方法的输出

python 闭包 + oop

ios - iPhone 上的 Apple Watch CoreMotion

ios - 如何获得两个 CGPath 的交集?