views:

39

answers:

1

I am writing an iPhone app where the user is supposed to be able to turn on and turn off all the pins on the map. To put all the pins on the map I use:

-(void) putAllPins {
    for (id key in myDictionary) { //A NSDictionary
        NSArray *data = [myDictionary objectForKey:key];
        [self putPin: data];
    }
    isShowingAllPins = TRUE;
}

-(CLLocationCoordinate2D) putPin:(NSArray *) data {
    NSNumber *lat = [data objectAtIndex:0];
    NSNumber *lon = [data objectAtIndex:1];
    NSString *name = [data objectAtIndex:2];
    NSString *info = [data objectAtIndex:3];

    CLLocationCoordinate2D coords = {[lat doubleValue], [lon doubleValue]};
    MyMapAnnotation *annotation = [[MyMapAnnotation alloc] initWithCoordinate:coords andName:name andInformation:info];
    [_mapView addAnnotation:annotation];
    [annotation release];
    return coords;
}

To remove them I use:

-(void) removeAllPins {
    NSMutableArray *toRemove = [NSMutableArray  arrayWithCapacity:([_mapView.annotations count] - 1)];
    for (id annotation in _mapView.annotations) {
        if (annotation != _mapView.userLocation) {
            [toRemove addObject:annotation];
        }
    }

    [_mapView removeAnnotations:toRemove];
}

It works fine to remove all the pins once and add them again. But as soon as I remove them a second time I get an EXC_BAD_ACCESS error. I have traced the problem to the dealloc method in my annotation class, but still don't know what to do. Any help is appreciated!

MyAnnotation.m:

@implementation MyAnnotation

@synthesize coordinate = _coordinate;

-(id) initWithCoordinate:(CLLocationCoordinate2D)coordinate andName:(NSString *)name andInformation:(NSString *)info {
    self = [super init];
    _coordinate = coordinate;
    _name = name;
    _info = info;

    return self;
}

-(NSString *)title {
    return [NSString stringWithFormat:@"PREFIX %@", _name];
}

-(NSString *)subtitle {
    return _info;
}

- (void)dealloc {
    [_name release];
    [_info release];
    [super dealloc];
}

@end
+1  A: 

Try tip #1 here

http://loufranco.com/blog/files/debugging-memory-iphone.html

You set Xcode so that objects aren't really released, and they complain if you release deallocated objects or in some other way send them a message.

Update: _name is never retained -- and then you release it. Same with _info. If they are retained properties, you need to use self._name to use the generated set message (that retains)

Lou Franco
Hmm, _name and _info are never retained and this should mean that the dealloc method isn't supposed to be there at all, I guess? After the removal of it, everything works fine. Thank you for pointing this out!
Ed Taylor
Not exactly. What is making sure these strings aren't deallocated under your class? The normal thing is to retain them if you want to send messages to them later and release in dealloc. You just need to make sure to balance retain/release.
Lou Franco