Frage

Sieht aus wie ich nicht die Speicherverwaltung in Objective C verstanden ... seufzen.

Ich habe den folgenden Code (beachten Sie, dass in meinem Fall placemark.thoroughfare und placemark.subThoroughfare sind beide mit gültigen Daten gefüllt, so dass beiden if-Bedingungen werden TRUE

item ist mit einem ManagedObjectContext gebunden. Die verwalteten Variablen in item wie place haben Setter / Getter mit @dynamic erstellt. Somit ist die Erklärung

@property (nonatomic, retain) NSString *place;
@dynamic place;

Später im Code, in dem ReverseGeocoderDelegate mich darauf zuzugreifen:

- (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];
}

Wenn ich nicht loslassen item.place an der markierten Stelle im Code, findet Instruments ein Speicherverlust gibt. Wenn ich das tue, stürzt das Programm, sobald ich den Zugriff auf item.place außerhalb der säumige Methode versuchen.

Irgendwelche Ideen?

War es hilfreich?

Lösung

First of all, I would change the logic like this:

NSString *newPlace = nil;

if (placemark.thoroughfare && placemark.subThoroughfare) {
    newPlace = [NSString stringWithFormat:@"%@ %@", placemark.thoroughfare , placemark.subThoroughfare];
}
else {
    if (placemark.thoroughfare) {
        newPlace = [NSString stringWithFormat:@"%@ ", placemark.thoroughfare];
    }
    else {
        newPlace = @"Unknown Place";
    }
}

item.place = newPlace;    // Either nil of valid string can be assigned to

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 its retainCount is 0.

Assuming your item has the property retain and since stringWithFormat: returns autoreleased string, so at the 2nd release, you were trying to release what was going to be autoreleased anyway.

Best way to clearing an object multiple times is simply assigning nil to it.

Andere Tipps

A starting point would be to re-read about properties because you don't need to do `[item.place release]' anywhere. So you can remove them. The dynamic code created by the runtime to enable that property automatically handles releasing anything previously assigned to it.

Also, the [NSString stringWithFormat:... creates an autorelease object (not sure if you knew that :-) which means that if you where manually managing the memory for a variable (not a property) then you would have to retain/release it. But because you are using properties, you don't.

I cannot see why instruments is finding a memory leak. Perhaps some code higher up is to do with it. For example if you went item.place = [NSString alloc] initWith...]; then I think you would need it.

The crash I would suspect to be because of the releases causing retain counts to be zero and triggering exec bad access errors.

Hope that helps.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top