Come rilasciare correttamente una variabile di istanza NSMutableDictionary, con dizionari nidificati, in Objective-C?

StackOverflow https://stackoverflow.com/questions/1402778

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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top