2012-09-09 3 views
0

MKMapView 및 MKPolyline을 사용하여 경로 모양을 표시하고 있습니다. 주석이 내 MKMapView에 배치되고 이미 다른 주석이 있으면 비동기 적으로 내 길 찾기 공급자에게 라우팅 호출을 보내고 모양의 오버레이를 추가합니다.MKOverlay가 비동기 호출에서 표시하는 데 오래 걸립니다.

여기에 문제가 있습니다. 요청에 주 스레드를 사용하면 요청이 진행되는 동안 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. 
    }); 
} 

나는 위의 코드를 가지고 비동기 지침을 주석하는 경우, 그것은을 처리 할 수있는 같은 시간이 걸린다는 성가신 동결을 유발, 하지만 오버레이는 바로 그려집니다 :

//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는 그것이 비동기 끝나면 오버레이를 그릴 필요 실현하기 위해 잠시 걸리는 이유는 어떤 생각?

감사 아우렐 리오

답변

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); 
    }); 
+0

감사합니다. Marco! 그 트릭을 ... –

관련 문제