Swift 异步函数滞后

标签 swift multithreading asynchronous mapkit

我在尝试调用 iOS MapKit 中的 .calculate 函数时遇到问题。我知道这个函数在与主线程不同的单独线程上运行,但我不知道如何在将控制权返回到主线程之前更新 walkingTime 的值。

class RouteManager {

    static let shared = RouteManager()
    var initialWalkingTime: Double!
    var finalWalkingTime: Double!
    private init() {

    }

    func calculateWalkingTime(
                from givenLocation: CLLocation,
                to givenStop: CLLocation,
                completion: @escaping (_ double: Double?, _ error: Error?) -> () ) {

        let sourcePlacemark = MKPlacemark(coordinate: givenLocation.coordinate)
        let sourceMapItem = MKMapItem(placemark: sourcePlacemark)
        let destinationPlacemark = MKPlacemark(coordinate: givenStop.coordinate)
        let destinationMapItem = MKMapItem(placemark: destinationPlacemark)
        var walkingTime: Double?

        let request = MKDirectionsRequest()
        request.source = sourceMapItem
        request.destination = destinationMapItem
        request.transportType = .walking
        request.requestsAlternateRoutes = false
        let directions = MKDirections(request: request)

        directions.calculate { response, error in
            if let route = response?.routes.first {
                walkingTime = (route.expectedTravelTime/60)
            }
            completion(walkingTime, error)
        }
    }

    func setupRoutes(from initialLocation: CLLocation, to finalLocation: CLLocation) {

        let startingLocation = BusManager.shared.startingLocation.location
        let endingLocation = BusManager.shared.endingLocation.location

        calculateWalkingTime(from: initialLocation, to: startingLocation) {(walkingTime, error) in
            guard let walkingTime = walkingTime, error == nil else {return}
            self.initialWalkingTime = walkingTime
        }

        calculateWalkingTime(from: endingLocation, to: finalLocation) {(walkingTime, error) in
            guard let walkingTime = walkingTime, error == nil else {return}
            self.finalWalkingTime = walkingTime
        }
    }
}

基本上,我的 RouteManager.shared.initialWalkingTimeRouteManager.shared.finalWalkingTime 用于我的 UI,因此我需要在它们离开我的 calculateWalkingTime 之前对其进行更新 函数。

我该如何去做呢?

最佳答案

假设计算足够短,嵌套它们可能就可以了:

func setupRoutes(from initialLocation: CLLocation, to finalLocation: CLLocation) {

    let startingLocation = BusManager.shared.startingLocation.location
    let endingLocation = BusManager.shared.endingLocation.location

    calculateWalkingTime(from: initialLocation, to: startingLocation) {(firstWalkingTime, error) in
        guard let firstWalkingTime = firstWalkingTime, error == nil else {return}

        calculateWalkingTime(from: endingLocation, to: finalLocation) {(secondWalkingTime, error) in
            guard let secondWalkingTime = secondWalkingTime, error == nil else {return}
            self.initialWalkingTime = firstWalkingTime
            self.finalWalkingTime = secondWalkingTime
        }
    }
}

请注意,在您的设计中,您可能应该将 self.initialWalkingTimeself.finalWalkingTime 设为可选,因为这是一个可能失败的过程。

关于Swift 异步函数滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46719949/

相关文章:

swift - 声明专门用于不同类型的通用结构数组

ios - 为什么 iPad 不会在结束编辑时关闭选择器 View ,但 iPhone 会

java - 如何以多线程方式调用不同类的相同方法

javascript - 是否可以将 web worker 与不包含在外部文件中的 JavaScript 一起使用?

swift - SceneKit切换场景内存泄漏

swift - 我如何在循环中链接 Swift 中的 promise ?

c# - 内存屏障与互锁对内存缓存一致性时序的影响

javascript - 访问异步函数返回的最佳方式

c# - 是否有像 Queue 这样的 C# 类实现 IAsyncEnumerable?

.net - 为什么 Task.WhenAll 上的等待不抛出 AggregateException?