Comment libérer correctement une variable d'instance NSMutableDictionary, avec des dictionnaires imbriqués, en Objective-C?

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

Question

J'ai une classe Objective-C qui ressemble à quelque chose comme:

@interface myClass : NSObject
{
    NSMutableDictionary *aDict;
}

Sa méthode de définition est la suivante:

- (void) setADict: (NSMutableDictionary *) newDict
{
    [aDict release];
    [newDict retain];
    aDict = newDict;
}

J'ai créé une instance de l'objet, mis des données dans aDict et je souhaite maintenant me débarrasser de cet objet en nettoyant sa mémoire. Deux questions:

1) Devrais-je publier aDict dans la méthode myClass de dealloc , comme indiqué?

[aDict release];

============================================ =================================

2) J'ai imbriqué plusieurs dictionnaires d'enfants dans aDict , représenté par keyA et keyB , comme suit:

// aDict:
{
    keyA =     {
        keyA1 = "Hello world";
        keyA2 = 1234;
    };
    keyB =     {
        keyB1 = Earth;
        keyB2 = 25000;
    };
}

Un message [aDict release] "se propagera-t-il tout au long de la chaîne" et nettoyer tous les dictionnaires d'enfants dans aDict, y compris leurs objets clé / valeur ? Ou dois-je faire autre chose pour m'en débarrasser?

Était-ce utile?

La solution

Oui.

Les objets de collection conservent les éléments qu'ils collectent. Ainsi, lorsque la collection est désallouée, il conserve l'équilibre entre une conservation et une version.

Ensuite, si l'un des dictionnaires qu'il conservait est désalloué, il publiera également ses paires clé / valeur, car le dictionnaire est une collection et les objets de la collection conservent les éléments qu'ils collectent.

Il en va de même pour les tableaux et les ensembles.

Cependant, votre code contient un bug. Vous avez:

- (void) setADict: (NSMutableDictionary *) newDict
{
    [aDict release];
    [newDict retain];
    aDict = newDict;
}

Considérons le cas où newDict est le même objet que aDict . Ensuite, vous libérez le dictionnaire, il est désalloué, puis vous essayez de le conserver, mais oups! Ce n'est plus là.

Il existe trois alternatives pour résoudre ce problème. Les voici:

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

Je dirais que le troisième est le plus simple, le second est le plus rapide dans le temps et le premier est meh . Le premier encombrera vos pools de libération automatique (ce qui peut ou non conduire à un gonflement de la mémoire). Les deuxième et troisième sont équivalents en termes de sécurité et de gestion de la mémoire de propriété. Cependant, le second vous évitera des appels de méthode inutiles si vous définissez le même dictionnaire sur lui-même.

Autres conseils

NSMutableDictionary libérera tous les objets (valeurs) lors de la validation.

NSMutableDictionary copie la clé et envoie la valeur de retenue à pour chaque paire clé / valeur que vous avez ajoutée. La pratique du cacao est la suivante: quand quelque chose conserve la référence, il est responsable de sa publication.

Voir la référence NSMutableDictionary

  

Méthodes qui ajoutent des entrées à   dictionnaires - que ce soit dans le cadre de   initialisation (pour tous les dictionnaires)   ou pendant la modification (pour mutable   dictionnaires) —copiez chaque argument clé   (les clés doivent être conformes à la NSCopying   protocole) et ajouter les copies au   dictionnaire. Chaque valeur correspondante   l'objet reçoit un message de conservation pour   s'assurer qu'il ne sera pas désalloué   avant la fin du dictionnaire   il.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top