【问题标题】:MKOverlay takes long to display from async callMKOverlay 需要很长时间才能从异步调用中显示
【发布时间】:2012-09-09 02:10:17
【问题描述】:

我正在使用 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 需要一段时间才能意识到它需要在异步完成时绘制叠加层吗?

谢谢 奥雷里奥

【问题讨论】:

    标签: ios mkmapview redraw mkoverlay dispatch-async


    【解决方案1】:

    您需要在主线程上更新地图视图(和所有 UI)。因此,在您的 dispatch_async 块内并在收到您的回复后:

       // 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);
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-14
      • 1970-01-01
      • 2019-10-10
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多