MKOverlayView производительность - PullRequest
2 голосов
/ 22 февраля 2012

Я добавляю около 3000 MKOverlay на свою карту, и, как вы можете себе представить, это занимает некоторое время, иногда до восьми секунд.Я ищу способ использовать многопоточность для повышения производительности, чтобы пользователь мог перемещать карту во время добавления наложений.Предпочтительно, чтобы наложения были добавлены последовательно, начиная с , равного , в пределах области карты.Я пытался что-то в этом духе с 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 голосов
/ 22 февраля 2012

Существует небольшой разрыв между тем, что вы хотите, и тем, что может сделать компилятор.Когда вы звоните dispatch_async, вы на самом деле говорите процессору « здесь, получите этот кусок кода и запускайте его всякий раз, когда захотите, а не сейчас, не блокируя поток моего пользовательского интерфейса ».Но ваш метод должен возвращать сейчас .У вас просто нет возможности создать что-либо в фоновом потоке, потому что вам придется ждать его в любом случае , прежде чем mapView:viewForOverlay: вернется, поскольку оно должно вернуть что-то .

Этот метод не место для использования GCD или любого фонового кода.Если ваша проблема заключается в добавлении большого количества наложений одновременно, я бы разделил все наложения на куски, скажем, 100, и добавил бы их на карту с задержкой 100 мс между каждым пакетом.

...