MKMapView と MKPolyline を使用してルート形状を表示しています。注釈が MKMapView に配置され、そこに別の注釈が既に存在する場合、ルート プロバイダーにルーティング コールを非同期的にディスパッチし、成形されたオーバーレイを追加します。
これが問題です。リクエストにメイン スレッドを使用すると、リクエストの進行中に MKAnnotation ドロップがフリーズしますが、戻るとオーバーレイが適切に表示されます。代わりにリクエストを非同期キューにディスパッチすると、アノテーション ドロップがフリーズせず、非同期呼び出しが完了するとオーバーレイが追加されますが、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.
});
}
上記のコードを取得して async ディレクティブをコメント アウトすると、処理に同じ時間がかかり、迷惑なフリーズが発生しますが、オーバーレイはすぐに描画されます。
//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 が非同期で行われたときにオーバーレイを描画する必要があることに気付くのに時間がかかる理由は何ですか?
ありがとうアウレリオ