我正在使用 MKMapView 和 MKPolyline 来显示路线形状。当在我的 MKMapView 上放置一个注释并且那里已经有另一个注释时,它会异步地向我的方向提供程序发送路由调用并添加形状覆盖。
问题来了。如果我将主线程用于请求,它会在请求进行时卡住 MKAnnotation 下降,但当它返回时,它会很好地显示覆盖。相反,如果我将请求分派(dispatch)到异步队列,则注释放置不会卡住,并且当异步调用完成时,它会添加叠加层,但 MapView 需要一段时间才能意识到这一点并实际绘制叠加层。有时需要 20 秒。这是代码。
//Action handler selector to drop the pin
-(void)dropWayPoint:(WayPoint*)wp prevWayPoint:(WayPoint*)prevWp {
[self.mapView addWayPoint: wp];
[self.routeService routeFrom:prevWp to:wp];
}
实际的路由计算在这里:
@implementation RouteService
static dispatch_queue_t queue;
+(RouteService) initRouteService:(id)delegate {
RouteService *rs = [[RouteService alloc] init];
//Lots of things happen here, including the queue creation
...
if (!queue) {
queue = dispatch_queue_create("RouteDispatch.queue", NULL);
}
return rs;
}
//Lots of methods...
//then
-(void)routeFrom:(WayPoint*)wp to:(WayPoint*)wpTp {
dispatch_async(queue, ^{
//Code here
DirectionsRouteRequest *rt = [DirectionsRouteRequest buildWithRouteType:@"fastest"];
[rt addObjectToLocation:[wp coord]];
[rt addObjectToLocation:[wpTp coord]];
rt.options.routeType = @"fastest";
NSLog(@"Dispatching...");
//Now send the request
DirectionsResponseType *response = [MapUtil computeDirections:rt];
Leg *leg = [Leg buildFromResponse:response route: self.route startWayPoint:wp endWayPoint:wpTp];
MKPolyline *pl = [MapUtil makePolylineWithLocations:[leg routeShape]];
[self.route.legsHash setObject:pl forKey:leg.legIdStr];
//Add Overlay here!!!
[self.mapDeskViewController.mapView addOverlay: pl];
//Desperately advising map view to redraw itself and show the overlay
[self.mapDeskViewController.mapView setNeedsDisplay];
//I can see this being displayed very quickly, meaning
NSLog(@"Response, pl_count:%d",pl.pointCount);
//However it takes a long time after this returns to actually display the overlay.
});
}
如果我采用上面的代码并注释掉异步指令,它会花费相同的时间来处理它,引发烦人的卡住,但会立即绘制叠加层:
//Lots of methods...
//then
-(void)routeFrom:(WayPoint*)wp to:(WayPoint*)wpTp {
/* COMMENTED OUT ASYNC
dispatch_async(queue, ^{
*/
//Code here
DirectionsRouteRequest *rt = [DirectionsRouteRequest buildWithRouteType:@"fastest"];
[rt addObjectToLocation:[wp coord]];
[rt addObjectToLocation:[wpTp coord]];
rt.options.routeType = @"fastest";
NSLog(@"Dispatching...");
//Now send the request
DirectionsResponseType *response = [MapUtil computeDirections:rt];
Leg *leg = [Leg buildFromResponse:response route: self.route startWayPoint:wp endWayPoint:wpTp];
MKPolyline *pl = [MapUtil makePolylineWithLocations:[leg routeShape]];
[self.route.legsHash setObject:pl forKey:leg.legIdStr];
//Add Overlay here!!!
[self.mapDeskViewController.mapView addOverlay: pl];
//Desperately advising map view to redraw itself and show the overlay
[self.mapDeskViewController.mapView setNeedsDisplay];
//I can see this being displayed very quickly, meaning
NSLog(@"Response, pl_count:%d",pl.pointCount);
/*
COMMENTED OUT ASYNC
});
*/
}
知道为什么 MKMapView 在异步完成时需要一段时间才能意识到它需要绘制叠加层吗?
谢谢 奥雷里奥
最佳答案
您需要在主线程上更新 map View (和所有 UI)。因此,在您的 dispatch_async block 中并在收到您的回复后:
// Create another block that gets queued up in the main_queue, a default serial queue
dispatch_async(dispatch_get_main_queue(), ^{
Leg *leg = [Leg buildFromResponse:response route: self.route startWayPoint:wp endWayPoint:wpTp];
MKPolyline *pl = [MapUtil makePolylineWithLocations:[leg routeShape]];
[self.route.legsHash setObject:pl forKey:leg.legIdStr];
//Add Overlay here!!!
[self.mapDeskViewController.mapView addOverlay: pl];
//Desperately advising map view to redraw itself and show the overlay
[self.mapDeskViewController.mapView setNeedsDisplay];
//I can see this being displayed very quickly, meaning
NSLog(@"Response, pl_count:%d",pl.pointCount);
});
关于ios - MKOverlay 需要很长时间才能从异步调用中显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12336006/