Frage

Jedes Mal, ich nenne diese Methode meines NSMutableData undicht ist und ich kann nicht herausfinden, wie es zu stopfen. theData des Beibehaltungszähler wird upped durch einen nach den Decodern zugewiesen und initialisiert wird, und ich habe keine Ahnung, warum. Ich stecke mit einer Zählung von 2 am Ende des Verfahrens zurückhalten und versuchen, sie zu lösen verursacht eine App zum Absturz bringen.

- (void)readVenueArchiveFile:(NSString *)inFile key:(NSString *)inKey
{
    NSMutableData *theData;
    NSKeyedUnarchiver *decoder;


    theData = [NSData dataWithContentsOfFile:inFile];

    decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];

    venueIOList = [[decoder decodeObjectForKey:inKey] mutableCopy];

    [decoder finishDecoding];

    [decoder release];
}
War es hilfreich?

Lösung

Ich würde diese Zeile empfehlen ersetzen:

venueIOList = [[decoder decodeObjectForKey:inKey] mutableCopy];

mit:

ListClassName *decodedList = [decoder decodeObjectForKey:inKey];
self.venueIOList = decodedList;

Das macht die Speicherverwaltung von decodedList klar. Es ist am beste Praxis als Instanzvariablen unter Verwendung eine Zugriffsmethode zuweisen (außer in init Methoden). In Ihrer aktuellen Implementierung, wenn Sie jemals readVenueArchiveFile: ein zweites Mal auf das gleiche Objekt aufrufen, können Sie Leck (wie Sie, wenn decodedList bereits einen Wert hat). Darüber hinaus können Sie die Kopie Logik in Ihrem Accessormethode setzen und lieber vergessen Sie es als mutableCopy Sie einen neuen Wert zuweisen jedes Mal, sich zu erinnern (vorausgesetzt, es einen guten Grund ist sowieso eine änderbare Kopie zu machen?).

Andere Tipps

Reduzierung der Spitzenspeicherbedarf

Im Allgemeinen ist es am beste Praxis betrachtet zu vermeiden Autoreleased Objekte zu erzeugen.

[Die meisten dieses Absatzes von diese Frage .] Sie sind typischerweise (1) haben keine direkte Kontrolle über ihre Lebensdauer, können Autoreleased Objekte für eine vergleichsweise lange Zeit bestehen bleiben und unnötig den Speicherbedarf der Anwendung erhöhen. Während auf dem Desktop diese können sein von geringer Bedeutung, auf eingeschränkteren Plattformen kann dies ein wichtiges Thema sein. Auf allen Plattformen daher und vor allem auf eingeschränkteren Plattformen, wo möglich, Sie verwenden Methoden dringend abgeraten werden, die Autoreleased Objekte führen würde und stattdessen ermutigt, die alloc / init Muster zu verwenden.

Ich würde dies vorschlagen ersetzen:

theData = [NSData dataWithContentsOfFile:inFile];

mit:

theData = [[NSData alloc] initWithContentsOfFile:inFile];

dann am Ende des Verfahrens hinzugefügt werden:

[theData release];

Das bedeutet, dass theData wird, bevor das Verfahren beendet freigegeben werden. Sie sollten am Ende mit:

- (void)readVenueArchiveFile:(NSString *)inFile key:(NSString *)inKey
{
    NSMutableData *theData;
    NSKeyedUnarchiver *decoder;

    theData = [[NSData alloc] initWithContentsOfFile:inFile];
    decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];
    ListClassName *decodedList = [decoder decodeObjectForKey:inKey];
    self.venueIOList = decodedList;
    [decoder finishDecoding];
    [decoder release];
    [theData release];

}

Das macht die Speicherverwaltung Semantik klar und reklamiert Speicher so schnell wie möglich.

(1) Sie können die Kontrolle übernehmen, indem Sie Ihre eigenen lokalen Autofreigabepools verwenden. Weitere Informationen hierzu finden Sie unter

Keine Sorge zählt behalten, Sorgen innerhalb einer Methode der Ausgewogenheit. Was Sie in diesem Verfahren zu tun korrekt aussieht, venueIOList Annahme ist eine Instanzvariable.

Um auf meiner Antwort ein wenig zu erweitern: Der Entpacker könnte Ihre Daten während des unarchive Betriebes wird beibehalten, und dann die Daten -autorelease zu senden, wenn es statt -release getan hat. Da das ist nicht etwas, Sie tat, es ist nicht etwas, Sie haben zu kümmern.

Ihr Code korrekt ist; es gibt keinen Speicherverlust.

theData = [NSData dataWithContentsOfFile:inFile];

entspricht

theData = [[[NSData alloc] initWithContentsOfFile:inFile] autorelease];

An diesem Punkt theData einen Referenzzähler von 1 hat (wenn auch weniger, wäre es freigegeben werden). Der Referenzzähler automatisch zu einem bestimmten Zeitpunkt in der Zukunft durch den Autofreigabepool verringert werden.

decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData];

Das Decoderobjekt hält eine Referenz auf die theData bis 2 die Referenzzähler inkrementiert.

Nach der Methode zurückgibt, der Autofreigabepool diesen Wert auf 1 dekrementiert Wenn Sie theData am Ende dieses Verfahrens loslassen, wird der Referenzzähler 0 wird, wird das Objekt freigegeben werden, und Ihre Anwendung abstürzen, wenn Sie versuchen, verwenden sie es.

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