MKOverlayView性能

时间:2012-02-22 01:32:29

标签: ios multithreading performance grand-central-dispatch mkoverlay

我在我的地图上添加了大约3000个MKOverlay,你可以想象,它需要一段时间,有时甚至长达8秒。我正在寻找一种使用线程来提高性能的方法,因此用户可以在添加叠加层时移动地图。优选地,叠加将顺序添加,从地图的区域内的那些开始。我在GCD上尝试过这些方法:

- (MKOverlayView*)mapView:(MKMapView*)mapView viewForOverlay:(id)overlay {
    __block MKPolylineView* polyLineView;

    //do the heavy lifting (I presume this is the heavy lifting part, but 
    // because this code doesn't compile, I can't actually *test* it)
    // on a background thread
    dispatch_async(backgroundQueue, ^ { 
        polyLineView = [[[MKPolylineView alloc] initWithPolyline:overlay] autorelease];
        [polyLineView setLineWidth:11.0];

        //if the title is "1", I want a blue line, otherwise red
        if([((LocationAnnotation*)overlay).title intValue]) {
            [polyLineView setStrokeColor:[UIColor blueColor]];
        } else {
            [polyLineView setStrokeColor:[UIColor redColor]];
        }

        //return the overlay on the main thread
        dispatch_async(dispatch_get_main_queue(), ^(MKOverlayView* polyLineView){
            return polyLineView;
        });
    });
}

但是因为GCD块是用void参数和返回类型定义的,所以这段代码不起作用 - 我在return行上得到了一个不兼容的指针类型错误。有没有我在这里缺少的东西,或其他方式来解决这个问题?或者可能是一种完全不同的方法来改善叠加过程的性能?我感谢任何帮助!

编辑:

我发现问题是我实际上添加叠加层:

for(int idx = 1; idx < sizeOverlayLat; idx++) {
    CLLocationCoordinate2D coords[2];
    coords[0].latitude = [[overlayLat objectAtIndex:(idx - 1)] doubleValue];
    coords[0].longitude = [[overlayLong objectAtIndex:(idx - 1)] doubleValue];

    coords[1].latitude = [[overlayLat objectAtIndex:idx] doubleValue];
    coords[1].longitude = [[overlayLong objectAtIndex:idx] doubleValue];

    MKPolyline* line = [MKPolyline polylineWithCoordinates:coords count:2];
    [line setTitle:[overlayColors objectAtIndex:idx]];

    [mapViewGlobal addOverlay:line];
}

添加全部3000可能需要100毫秒。花费很长时间(我假设)的部分是我实际上创建叠加层的地方,在我展示的第一个方法中。

1 个答案:

答案 0 :(得分:0)

你想要什么和编译器可以做什么之间有一点差距。当你打电话给dispatch_async时,你实际上在告诉CPU“这里,拥有这块代码,并在你想要的时候运行它,而不是现在,不阻止我的用户界面线程 ”。但是,您的方法必须返回现在。您无法在后台线程中创建任何内容,因为在mapView:viewForOverlay:返回之前您将不得不等待它 ,因为它必须返回

此方法不是使用GCD或任何后台代码的地方。如果您的问题是同时添加了大量叠加层,我会将所有叠加层拆分为100块,并将它们添加到地图中,每批次之间的延迟时间为100毫秒。