首页 > 解决方案 > 在“for in”循环中初始化的计时器为每个循环触发两次

问题描述

我正在构建一个使用 MapKit 在地图上显示自定义驾驶路线的应用程序。它接受一个坐标数组并通过一个for循环,在每个循环中,相应的坐标(即[0]和[1]或[7]和[8])被组装成一个单独的请求,然后在地图上绘制。

为了绕过 MapKit 的限制错误,我设置了一个计时器,以便每个请求间隔 1 秒。

我的问题是计时器为每个单独的请求触发两次,这导致发出的必要请求数量增加了一倍。

我正在使用 Xcode 10 和 Swift 4,这是我认为出现问题的函数。

func requestDirections(arrays coordinates: [CLLocationCoordinate2D]) {

    var dest = 1
    let coordinatesArray = coordinates
    let end = coordinatesArray.count - 2
    var timerDelay:Double = 1

    for origin in 0...end {

        if dest <= coordinatesArray.count {

            let startCoord = MKPlacemark(coordinate: coordinatesArray[origin])
            let destCoord = MKPlacemark(coordinate: coordinatesArray[dest])

            let request = MKDirections.Request()
            request.source = MKMapItem(placemark: startCoord)
            request.destination = MKMapItem(placemark: destCoord)
            request.transportType = .automobile
            request.requestsAlternateRoutes = false

            print("Starting timer for \(dest) at \(timerDelay) seconds")

            Timer.scheduledTimer(withTimeInterval: timerDelay, repeats: false) { timer in
                self.createIndividualDirectionsRequest(request)
                print("Timer fired")
            }

            dest = dest + 1
            timerDelay = timerDelay + 1

        }
    }
}

我希望计时器为每个循环触发一次,如果发生这种情况,预期的控制台输出将是

“在 'timerDelay' 秒处启动 'dest' 的计时器”打印 18 次(或者无论数组的大小是多少)

“定时器触发”也被打印了 18 次

虽然“在 'timerDelay' 秒处启动 'dest' 的计时器”实际上打印了正确的次数,但“计时器已触发”的打印频率是应有的两倍。

非常感谢您的帮助和耐心,我对编程很陌生,并且正在努力解决这个问题。

标签: swiftloopstimer

解决方案


实际上,我不知道为什么每个单独的请求都会打印两次“定时器触发” :)

但是如果你Timer.scheduledTimer只是用来延迟块的执行,你可以使用DispatchQueue.main.asyncAfter而不是 Timer

DispatchQueue.main.asyncAfter(deadline: .now() + timerDelay) {
     self.createIndividualDirectionsRequest(request)
     print("Timer fired")
}

您也可以使用DispatchQueue.global.asyncAfter,但我认为您想在主 ui 线程中执行该块


推荐阅读