Удаление наложений MKMapView в iOS не работает

Я хотел бы удалить все оверлеи моей карты в одной точке, и я пробовал разные способы, но это никогда не срабатывало.

Последняя попытка, которую я сделал [self.mapView removeOverlays:self.mapView.overlays];, все еще не работает. Любая идея, как я могу удалить эти наложения?

Спасибо.

ОБНОВЛЕНИЕ 1

У меня ошибка: malloc: *** error for object 0x5adc0c0: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug

Я думаю, что знаю, почему, но не знаю, как это исправить... Вот код, когда мне нужно нарисовать еще одну линию на моем mapView:

// Create a c array of points. 
MKMapPoint *pointsArray = malloc(sizeof(CLLocationCoordinate2D) * 2);

// Create 2 points.
MKMapPoint startPoint = MKMapPointForCoordinate(CLLocationCoordinate2DMake(oldLatitude, oldLongitude));
MKMapPoint endPoint = MKMapPointForCoordinate(CLLocationCoordinate2DMake(newLatitude, newLongitude));

// Fill the array.
pointsArray[0] = startPoint;
pointsArray[1] = endPoint;

// Erase polyline and polyline view if not nil.
if (self.routeLine != nil) {
    [_routeLine release];
    self.routeLine = nil;
}

if (self.routeLineView != nil) {
    [_routeLineView release];
    self.routeLineView = nil;
}

// Create the polyline based on the array of points.
self.routeLine = [MKPolyline polylineWithPoints:pointsArray count:2];

// Add overlay to map.
[self.mapView addOverlay:self.routeLine];

// clear the memory allocated earlier for the points.
free(pointsArray);

// Save old coordinates.
oldLatitude = newLatitude;
oldLongitude = newLongitude;

Поэтому я освобождаю объект routeLine, который является предыдущим наложением. Поэтому, когда я попытался удалить его, он вылетает, потому что он уже был освобожден.

Вот код делегата mapView для добавления оверлейных представлений:

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
    MKOverlayView* overlayView = nil;

    if(overlay == _routeLine) {
        // If we have not yet created an overlay view for this overlay, create it now. 
        if(self.routeLineView == nil) {
            self.routeLineView = [[[MKPolylineView alloc] initWithPolyline:_routeLine] autorelease];

            self.routeLineView.fillColor = [UIColor blueColor];
            self.routeLineView.strokeColor = [UIColor blueColor];

            // Size of the trace.
            self.routeLineView.lineWidth = routeLineWidth;
        }

        overlayView = self.routeLineView;
    }

    return overlayView;
}

Если вы, ребята, знаете, как я могу решить эту проблему, удалив все наложения из моего MKMapView, это было бы здорово!

ОБНОВЛЕНИЕ 2

Я попытался не выпускать свои объекты routeLine и routeLineView, и теперь это работает. Утечек вроде тоже нет. Итак, сейчас я делаю это:

// Erase polyline and polyline view if not nil.
if (self.routeLine != nil) {
    //[_routeLine release];
    self.routeLine = nil;
}

if (self.routeLineView != nil) {
    //[_routeLineView release];
    self.routeLineView = nil;
}

person Dachmt    schedule 16.06.2011    source источник


Ответы (3)


Когда вы вызываете removeOverlays:, представление карты освободит объекты MKOverlay и MKOverlayView.

У вас есть собственные ссылки на них в _routeLine и _routeLineView.

После вызова removeOverlays: ваши переменные будут указывать на уже освобожденную память. Когда вы заново создаете полилинию, вы чрезмерно отпускаете, что приводит к сбою.

Итак, удалите вызовы release:

if (_routeLine != nil) {
    [_routeLine release];  // <-- remove this
    self.routeLine = nil;
}

if (_routeLineView != nil) {
    [_routeLineView release];  // <-- remove this
    self.routeLineView = nil;
}
person Community    schedule 16.06.2011
comment
Я так и сделала :) Большое спасибо @Anna Karenina! - person Dachmt; 16.06.2011

Когда вы выполняете код в отладчике, где появляется ошибка?

Одна мысль, у вас может быть проблема с вашим циклом сохранения/релиза для self.routeLine и self.routeLineView. Предполагая, что это свойства с атрибутом retain, когда вы делаете

self.routeLine = [MKPolyline polylineWithPoints:pointsArray count:2];  

ваш синтезированный метод доступа сохраняет новый объект MKPolyline. Этот объект также будет иметь пару сохранения/автоосвобождения из вспомогательного метода, который его создал. Когда этот метод вызывается снова, и вы вызываете

if (self.routeLine != nil) {
    [_routeLine release];
    self.routeLine = nil;
}

кода, вы в конечном итоге выпустите переменную дважды, первый раз с явным вызовом [_routeLine release], а второй с синтезированным аксессором при вызове self.routeLine = nil;. Он останется в памяти, но приведет к сбою приложения, когда ваш пул автовыпуска будет исчерпан.

В большинстве случаев, чтобы очистить все наложения на MKMapView (названном mapView в этом примере), я бы сделал что-то вроде следующего:

for (id<MKOverlay> overlayToRemove in mapView.overlays)
{
   if ([overlayToRemove isKindOfClass:[OverlayClassToRemove class]])
   {
       [mapView removeOverlay:overlayToRemove];
   }
}
person Kongress    schedule 16.06.2011
comment
Метод polylineWithPoints:count: принимает массив C структур MKMapPoint. - person ; 16.06.2011
comment
Мне нравится способ удаления наложений, который вы мне сказали, и я подумал, что это сработает или, по крайней мере, не приведет к сбою приложения. Но это произошло, и у меня такая же ошибка. @Анна Каренина Тогда я правильно храню баллы? Я пытался сохранить в NSArray и все равно не могу добавить в него этот тип объекта. - person Dachmt; 16.06.2011
comment
@Dachmt и @Анна Каренина, я исправляюсь. Вот что я получаю, когда угадываю вещи, которых сам не делал. Я отредактирую свой ответ. - person Kongress; 16.06.2011
comment
Я удалил [_routeLine release]; и [_routeLineView release];, и теперь все работает. Пожалуйста, просмотрите ОБНОВЛЕНИЕ 2 и дайте мне знать, если вы считаете, что что-то не так. - person Dachmt; 16.06.2011
comment
@Dachmt Имеет смысл. Извините, я не закончил редактирование до того, как вы это поняли :) - person Kongress; 16.06.2011

Расширение Swift 3

extension MKMapView
{
    func removeAllOverlay(){
        for overlay:MKOverlay in self.overlays  {
            self.remove(overlay)
        }
    }

}
person Varun Naharia    schedule 06.04.2017