使用异步方法关闭 (Swift 2.0)
Closure with asynchronous method (Swift 2.0)
我正在从事一个计算 MapView 上不同坐标之间的 ETA 的项目。我使用异步方法 calculateETAWithCompletionHandler
获取两个坐标之间的 ETA,因为 calculateETAWithCompletionHandler
是异步的,所以我的代码不是线性的。
我需要我的代码是线性的,以便在 TableView 中显示正确的 ETA 信息,因此我尝试在异步调用中实现对 return 的闭包。但是,这仍然没有使我的代码线性化。以下是我目前的情况,
override func viewDidLoad() {
var etaBetween1n2 = 0
let point1 = MKPointAnnotaion()
point1.coordinate = CLLocationCoordinate2D(latitude: 36.977317, longitude: -122.054255)
point1.title = "Point 1"
mapView.addAnnotation(point1)
let point2 = MKPointAnnotaion()
point2.coordinate = CLLocationCoordinate2D(latitude: 36.992781, longitude: -122.064729)
point2.title = "Point 2"
mapView.addAnnotation(point2)
print("A")
// Closure
calculateETA(point1, destination: point2) { (eta: Int) -> Void in
print("B")
etaBetween1n2 = eta
}
print("C")
}
// Calculates ETA between source and destination
// Makes calculateETAWithCompletionHandler call which is asynchronous
func calculateETA(source: MKPointAnnotation, destination: MKPointAnnotation, result: (eta: Int) -> Void) {
var eta = 0
let request = MKDirectionsRequest()
let sourceItem = MKMapItem(placemark: MKPlacemark(coordinate: source.coordinate, addressDictionary: nil))
request.source = sourceItem
request.transportType = .Automobile
let destinationItem = MKMapItem(placemark: MKPlacemark(coordinate: destination.coordinate, addressDictionary: nil))
request.destination = destinationItem
request.destination = destinationItem
request.requestsAlternateRoutes = false
let directions = MKDirections(request: request)
directions.calculateETAWithCompletionHandler { (etaResponse, error) -> Void in
if let error = error {
print("Error while requesting ETA : \(error.localizedDescription)")
} else {
eta = Int((etaResponse?.expectedTravelTime)!)
result(eta: eta)
}
}
}
我希望闭包可以通过打印使我的代码线性化,
A
B
C
但它仍然打印,
A
C
B
我是不是错误地实现了闭包,或者闭包是错误的方法?
所以闭包是一个回调,这意味着它在调用该函数后继续 运行 代码的其余代码,然后一旦准备就绪,它将 运行 回调函数。
所以如果你想在它完成后做一些事情,那么你会把它放在回调中,所以你把 print("B")
如果您可以计算某些东西,您的代码不应该是线性的,因为它会冻结主线程并且屏幕会变得无响应,直到操作完成。
之后你想做什么?
如果您希望 "C" 在 B 之后发生,那么您必须从闭包中调用它:
print("A")
calculateETA(point1, destination: point2) { (eta: Int) -> Void in
print("B")
etaBetween1n2 = eta
print("C")
}
If "C" 比简单的 print 语句复杂一步,我敢肯定。将其封装在一个函数中,并在闭包中调用该函数。
doStepA()
calculateETA(point1, destination: point2) { (eta: Int) -> Void in
doStepB()
etaBetween1n2 = eta
doStepC()
}
}
func doStepA() {
print("A")
}
func doStepB() {
print("B")
}
func doStepC() {
print("C")
}
我正在从事一个计算 MapView 上不同坐标之间的 ETA 的项目。我使用异步方法 calculateETAWithCompletionHandler
获取两个坐标之间的 ETA,因为 calculateETAWithCompletionHandler
是异步的,所以我的代码不是线性的。
我需要我的代码是线性的,以便在 TableView 中显示正确的 ETA 信息,因此我尝试在异步调用中实现对 return 的闭包。但是,这仍然没有使我的代码线性化。以下是我目前的情况,
override func viewDidLoad() {
var etaBetween1n2 = 0
let point1 = MKPointAnnotaion()
point1.coordinate = CLLocationCoordinate2D(latitude: 36.977317, longitude: -122.054255)
point1.title = "Point 1"
mapView.addAnnotation(point1)
let point2 = MKPointAnnotaion()
point2.coordinate = CLLocationCoordinate2D(latitude: 36.992781, longitude: -122.064729)
point2.title = "Point 2"
mapView.addAnnotation(point2)
print("A")
// Closure
calculateETA(point1, destination: point2) { (eta: Int) -> Void in
print("B")
etaBetween1n2 = eta
}
print("C")
}
// Calculates ETA between source and destination
// Makes calculateETAWithCompletionHandler call which is asynchronous
func calculateETA(source: MKPointAnnotation, destination: MKPointAnnotation, result: (eta: Int) -> Void) {
var eta = 0
let request = MKDirectionsRequest()
let sourceItem = MKMapItem(placemark: MKPlacemark(coordinate: source.coordinate, addressDictionary: nil))
request.source = sourceItem
request.transportType = .Automobile
let destinationItem = MKMapItem(placemark: MKPlacemark(coordinate: destination.coordinate, addressDictionary: nil))
request.destination = destinationItem
request.destination = destinationItem
request.requestsAlternateRoutes = false
let directions = MKDirections(request: request)
directions.calculateETAWithCompletionHandler { (etaResponse, error) -> Void in
if let error = error {
print("Error while requesting ETA : \(error.localizedDescription)")
} else {
eta = Int((etaResponse?.expectedTravelTime)!)
result(eta: eta)
}
}
}
我希望闭包可以通过打印使我的代码线性化,
A
B
C
但它仍然打印,
A
C
B
我是不是错误地实现了闭包,或者闭包是错误的方法?
所以闭包是一个回调,这意味着它在调用该函数后继续 运行 代码的其余代码,然后一旦准备就绪,它将 运行 回调函数。
所以如果你想在它完成后做一些事情,那么你会把它放在回调中,所以你把 print("B")
如果您可以计算某些东西,您的代码不应该是线性的,因为它会冻结主线程并且屏幕会变得无响应,直到操作完成。
之后你想做什么?
如果您希望 "C" 在 B 之后发生,那么您必须从闭包中调用它:
print("A")
calculateETA(point1, destination: point2) { (eta: Int) -> Void in
print("B")
etaBetween1n2 = eta
print("C")
}
If "C" 比简单的 print 语句复杂一步,我敢肯定。将其封装在一个函数中,并在闭包中调用该函数。
doStepA()
calculateETA(point1, destination: point2) { (eta: Int) -> Void in
doStepB()
etaBetween1n2 = eta
doStepC()
}
}
func doStepA() {
print("A")
}
func doStepB() {
print("B")
}
func doStepC() {
print("C")
}