Looks like I did not understand memory management in Objective C… sigh.
I have the following code (note that in my case, placemark.thoroughfare and placemark.subThoroughfare are both filled with valid data, thus both if-conditions will be TRUE
item is tied to a ManagedObjectContext. The managed variables in item such as place have setters/getters created with @dynamic. Thus, the declaration is
@property (nonatomic, retain) NSString *place;
@dynamic place;
Later in the code, in the ReverseGeocoderDelegate, I access it:
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
if (placemark.thoroughfare) {
[item.place release];
item.place = [NSString stringWithFormat:@"%@ ", placemark.thoroughfare];
} else {
[item.place release];
item.place = @"Unknown Place";
}
if (placemark.thoroughfare && placemark.subThoroughfare) {
// *** problem is here ***
[item.place release];
item.place = [NSString stringWithFormat:@"%@ %@", placemark.thoroughfare , placemark.subThoroughfare];
}
If I do not release item.place at the marked location in the code, Instruments finds a memory leak there. If I do, the program crashes as soon as I try to access item.place outside the offending method.
Any ideas?
First of all, I would change the logic like this:
Using release for simply re-initializing pointer is not so recommended by many. You don’t have to do this if it was to save some memory.
Your previous logic does releasing twice. What release does initially is simply decrementing
retainCount. If it’s 0, then the object is deallocated. Object will not be deallocated until itsretainCountis 0.Assuming your item has the property retain and since
stringWithFormat:returnsautoreleasedstring, so at the 2nd release, you were trying to release what was going to beautoreleasedanyway.Best way to clearing an object multiple times is simply assigning
nilto it.