【问题标题】:Swift completion handlerSwift 完成处理程序
【发布时间】:2017-10-28 18:10:58
【问题描述】:

我有一个闭包计算两点之间的距离和时间,但我需要提取闭包之外的值数组(方向和旅程时间)。

我很确定完成处理程序是可行的方法,但不太确定如何实现它。

我的代码:

var completionHandlers: [() -> Void] = []

@IBAction func calculateItinerary(_ sender: Any) {

    // start calc   

    for index in 0...coordsOfCollective.count - 2 { 

        let sourceLocation = MKPlacemark(coordinate: coordsOfCollective[index]) 

        let destinationLocation = MKPlacemark(coordinate: coordsOfCollective[index + 1])

        let sourceMapItem = MKMapItem(placemark: sourceLocation)
        let destinationMapItem = MKMapItem(placemark: destinationLocation)

        let request = MKDirectionsRequest()
        request.source = sourceMapItem
        request.destination = destinationMapItem

        request.transportType = .automobile
        request.requestsAlternateRoutes = false


        let directions = MKDirections(request: request)

        directions.calculate { response, error in
            if let route = response?.routes.first {
               print("Distance: \(route.distance/1000) km, ETA: \(route.expectedTravelTime/60) mins")

            self.distances.append(route.distance/1000)
            self.journeyTimes.append(route.expectedTravelTime/60)

                print(self.distances)
                print(self.journeyTimes)

                completionHandlers.append(?????)

            } else {
                print("Error!")
            }

        }
    }

print(completionHandlers)

}

directions.calculate 有一个 calculate(completionHandler: @escaping MKDirectionsHandler) 声明,所以我可以看到它是一个转义闭包。但我不知道如何在其中提取距离和旅程时间数组。打印函数当前产生值,但无法从其他地方访问。

感谢任何帮助。谢谢。

【问题讨论】:

    标签: ios swift


    【解决方案1】:
    var completionHandlers: [() -> Void] = []
    
    for i in 1...10 {
    
        let handler = {
    
            print(i)
    
        }
    
        completionHandlers.append(handler)
    
    }
    

    之后您可以执行处理程序:

    completionHandlers[0]()
    

    或者,使代码更具表现力:

    let handler = completionHandlers[0]
    handler()
    

    并通过所有处理程序:

    completionHandlers.forEach { handler in
        handler()
    }
    

    请注意,当您将处理程序存储在数组中时,您对它有一个强引用。因为闭包对你在闭包中引用的所有内容保持强引用,所以当你引用 self 时很容易创建一个引用循环:

    let handler = {
        self.myFunction()
    }
    

    您可以通过对 self 进行弱引用来避免重新定义:

    let handler = { [weak self] in
        self?.myFunction()
    }
    

    【讨论】:

    • 谢谢马塞尔。所以我本质上是将我的计算存储为处理程序,然后将其附加到 completionHandler 数组?
    • 为什么要在闭包之外处理计算?您可以使用 .calculate { [weak self] response, error in 确保不会对 self 进行强引用
    • 我正在尝试将计算结果传递给另一个视图控制器。所以我认为最好的方法是制作一系列结果,然后将它们传递给 segue。
    • 为什么不将结果添加到数组,而不是闭包?
    猜你喜欢
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多