MKMapKit - EXC_BAD_ACCESS при циклическом просмотре MKAnnotations - PullRequest
1 голос
/ 03 июня 2011

Я застрял на этой ошибке EXC_BAD_ACCESS уже 2 дня.У меня есть метод reloadAnnotations, который удаляет все аннотации перед добавлением новых аннотаций.Перед удалением аннотации этот метод должен проверить, содержит ли новый набор то же место, чтобы он не был удален и повторно добавлен.Но как только я пытаюсь отследить текущий заголовок аннотации, я получаю эту ошибку Thread 1: Program received signal: "EXC_BAD_ACCESS"

И когда я просматриваю аннотацию в отладчике, свойство title говорит «Недопустимая сводка».Это должно быть вызвано тем, что значение не сохраняется, но я все перепробовал и не могу понять.

Почему я не могу записать заголовок аннотации в NSLog?

И почему я не могу сравнить каждый заголовок и координаты с другими объектами?

BrowseController.m

-(void)reloadAnnotations
{
    NSMutableArray *toRemove = [NSMutableArray arrayWithCapacity:10];
    for (id annotation in _mapView.annotations) {
        if (annotation != _mapView.userLocation) {
            //ParkAnnotation *pa = (ParkAnnotation *)annotation;
            ParkAnnotation *pa = annotation;
            NSLog(@"pa.title %@", pa.title); // Thread 1: Program received signal: "EXC_BAD_ACCESS"
            [toRemove addObject:annotation];
        }
    }
    // DON'T REMOVE IT IF IT'S ALREADY ON THE MAP!!!!!! 
    for(RKLocation *loc in locations) 
    {
        CLLocationCoordinate2D location;
        location.latitude = (double)[loc.lat doubleValue];
        location.longitude = (double)[loc.lng doubleValue];
        ParkAnnotation *parkAnnotation = [[ParkAnnotation alloc] initWithTitle:loc.name andCoordinate:location];      
        [_mapView addAnnotation:parkAnnotation];
    }
    [_mapView removeAnnotations:toRemove];
}



- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
    NSLog(@"BrowseViewController map viewForAnnotation");
    MKPinAnnotationView *pin = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier: @"anIdentifier"];

    if (pin == nil){
        pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                               reuseIdentifier: @"anIdentifier"] autorelease];

        pin.pinColor = MKPinAnnotationColorRed;
        pin.animatesDrop = YES;
        pin.canShowCallout = YES;
    }
    else{
        pin.annotation = annotation;
    }
    return pin;
    }

ParkAnnotation.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface ParkAnnotation : NSObject <MKAnnotation> {

    NSString *title;
    CLLocationCoordinate2D coordinate;

}


@property (nonatomic, copy) NSString *title;  
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d;

@end

ParkAnnotation.m (отредактировано: см. Комментарии Вольфганга ниже)

#import "ParkAnnotation.h"
@implementation ParkAnnotation
@synthesize title, coordinate;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d {
    self = [super init];
    if (self) { 
        title = ttl;
        coordinate = c2d;    
    } 
    return self;
}
- (void)dealloc {
    [title release];
    [super dealloc];
}
@end

Ответы [ 2 ]

3 голосов
/ 03 июня 2011

Несмотря на то, что вы объявили, title имеет свойство типа copy, оно никогда не копируется, поскольку вы не используете метод установки и назначены напрямую. Вы даже выпускаете это без собственности. Измените это так,

title = [ttl copy];
0 голосов
/ 03 июня 2011

Инициализатор в ParkAnnotation.m не записан в соответствии с соглашениями ObjC. Переменная self никогда не устанавливается, назначенный инициализатор класса должен следовать следующей схеме:

- (id)init 
{
    self = [super init]; 
    if (self) 
    { 
        /* custom initialization here ... */ 
    } 
    return self;
} 

Поскольку self не установлено, методы доступа, используемые в вызывающей программе, завершатся с ошибкой; Контейнерный объект (внутри ParkAnnotation.m , на который ссылается self ) будет иметь нулевое или некоторое поддельное значение при попытке получить доступ к свойству внутри объекта из другого класса.

...