Come rilasciare correttamente una variabile di istanza NSMutableDictionary, con dizionari nidificati, in Objective-C?
-
05-07-2019 - |
Domanda
Ho una classe Objective-C che assomiglia a:
@interface myClass : NSObject
{
NSMutableDictionary *aDict;
}
Il suo metodo setter appare come:
- (void) setADict: (NSMutableDictionary *) newDict
{
[aDict release];
[newDict retain];
aDict = newDict;
}
Ho creato un'istanza dell'oggetto, messo i dati in aDict e ora voglio liberarmi dell'oggetto, ripulendo la sua memoria nel processo. Due domande:
1) Devo rilasciare aDict nel metodo dealloc di myClass , come mostrato?
[aDict release];
=============================================== ==============================
2) Ho nidificato diversi dizionari per bambini in aDict , rappresentato da tasto A e tasto B , in questo modo:
// aDict:
{
keyA = {
keyA1 = "Hello world";
keyA2 = 1234;
};
keyB = {
keyB1 = Earth;
keyB2 = 25000;
};
}
Il messaggio [aDict release] si propagherà lungo la catena " e ripulire tutti i dizionari per bambini all'interno di aDict, inclusi gli oggetti chiave / valore ? Oppure devo fare qualcos'altro per sbarazzarmi di loro?
Soluzione
Sì.
Gli oggetti Collection mantengono le cose che stanno collezionando, quindi quando la collezione è deallocata, bilancia la conservazione con un rilascio.
Quindi, se uno dei dizionari su cui stava trattenendo è deallocato, rilascerà anche le sue coppie chiave / valore, poiché il dizionario è una raccolta e gli oggetti della raccolta mantengono le cose che stanno raccogliendo.
Lo stesso vale per array e set.
Tuttavia, hai un bug nel tuo codice. Hai:
- (void) setADict: (NSMutableDictionary *) newDict
{
[aDict release];
[newDict retain];
aDict = newDict;
}
Considerare il caso in cui newDict
è lo stesso oggetto di aDict
. Quindi rilasci il dizionario, viene deallocato e quindi provi a conservarlo, ma urla! Non è più lì.
Esistono tre alternative per risolvere questo problema. Eccoli:
- (void) setADict: (NSMutableDictionary *) newDict
{
[aDict autorelease];
[newDict retain];
aDict = newDict;
}
- (void) setADict: (NSMutableDictionary *) newDict
{
if (aDict != newDict) {
[aDict release];
[newDict retain];
aDict = newDict;
}
}
- (void) setADict: (NSMutableDictionary *) newDict
{
[newDict retain];
[aDict release];
aDict = newDict;
}
Direi che il terzo è il più semplice, il secondo è il più veloce nel tempo e il primo è meh . Il primo ingombrerà i pool di rilascio automatico (che possono o meno portare a un gonfiamento della memoria). Il secondo e il terzo sono equivalenti in termini di sicurezza e gestione della memoria delle proprietà. Tuttavia, il secondo ti farà risparmiare inutili chiamate di metodo se ti capita di impostare lo stesso dizionario su se stesso.
Altri suggerimenti
NSMutableDictionary
rilascerà tutti gli oggetti (valori) al rilascio.
NSMutableDictionary
copia la chiave e invia la conservazione al valore per ogni coppia chiave / valore aggiunta. La pratica del cacao è che quando qualcosa mantiene un riferimento, è responsabile del rilascio.
Vedi riferimento NSMutableDictionary
Metodi che aggiungono voci a dizionari, sia come parte di inizializzazione (per tutti i dizionari) o durante la modifica (per mutevole dizionari): copia ogni argomento chiave (le chiavi devono essere conformi a NSCopying protocollo) e aggiungere le copie al file dizionario. Ogni valore corrispondente L'oggetto riceve un messaggio di conservazione a assicurarsi che non venga deallocato prima che il dizionario sia finito con esso.