2011-04-13 6 views
0

J'ai un grand NSDictionary avec un NSDictionary plus petit à l'intérieur. Je veux libérer le plus gros et retenir le second. J'ai ce code dans ma méthode init:Objectif-C: Conserver un NSDictionary dans un NSDictionary autoreleased

// Autoreleased stage dictionary 
NSString *plistPath = [[NSBundle mainBundle] pathForResource:map ofType:@"plist"]; 
NSDictionary *mapDict = [NSDictionary dictionaryWithContentsOfFile:plistPath]; 

// Owned items 
citiesDictionary = [[mapDict objectForKey:@"Cities"] retain]; 

citiesDictionary est déclaré dans l'interface de classe comme:

NSDictionary *citiesDictionary; 

Si j'essaie de libérer citiesDictionary en dealloc utilisant la ligne suivante, il se bloque.

[citiesDictionary release]; 

Mais si je ne dealloc citiesDictionary, je reçois une fuite de mémoire rapportée dans Instruments quand je dealloc la classe contenant citiesDictionary. Je reconnais que mapDict est désaffecté à la fin de init. Est-ce que cette désaffectation affecte citiesDictionary même si j'ai appelé retenir?

Si oui, comment puis-je conserver le plus petit dictionnaire tout en libérant le plus grand contenant? J'ai essayé différentes choses lors de l'attribution de citiesDictionary, mais rien ne semble fonctionner correctement. Certaines des approches que j'essayé:

citiesDictionary = [[mapDict objectForKey:@"Cities"] copy]; 

et

citiesDictionary = [NSDictionary initWithDictionary:[mapDict objectForKey:@"Cities"]]; 

et même

citiesDictionary = [NSDictionary initWithDictionary:[[mapDict objectForKey:@"Cities"] copy]]; 

Toute aide est appréciée. Je vous remercie.

Répondre

0

Merci pour vos commentaires les gars. Après des heures de coups de tête contre le problème, j'ai découvert ce qui l'a causé.C'était complètement de ma faute: j'introduisais une classe custom défectueuse de gestion de mémoire dans un NSMutableDictionary lié au citiesDictionary, et libérant cette autre chose causait la corruption de la mémoire.

Maintenant, les deux

citiesDictionary = [[mapDict objectForKey:@"Cities"] release]; 

et

citiesDictionary = [[mapDict objectForKey:@"Cities"] copy]; 

fonctionnent parfaitement bien. PS: Stords de StackOverflow: Étant donné que la solution au problème était complètement sans rapport avec la question principale, devrais-je aller voter cette question pour la suppression, ou la garder pour référence?

+0

J'accepterais votre propre réponse et voterais les réponses qui vous ont aidé à le comprendre. –

+0

Déjà levé les a votés, merci. –

1

Copiez le dictionnaire à citiesDictionary. Maintenant, vous pouvez être sûr d'avoir une copie du dictionnaire même si l'objet conteneur peut être libéré à tout moment. N'oubliez pas de publier ensuite le dictionnaire citiesDictionary.

Notez que lorsque vous utilisez copy, vous obtiendrez toujours un NSDictionary immutable même si l'objet original était un NSMutableDictionary. Utilisez mutableCopy pour obtenir un NSMutableDictionary si nécessaire.

+0

Merci pour votre réponse. J'ai prolongé la question avec certaines choses que j'ai essayées. J'ai déjà essayé de copier le dictionnaire, mais il se plante sur [version citiesDictionary] quand même. –

+1

Êtes-vous sûr de ne pas publier 'citiesDictionary' ailleurs que dans votre code en plus de' -dealloc'? –

+0

Oui, je suis pratiquement sûr de ne pas le désaffecter explicitement ailleurs. –

1

Vous êtes en train de surcharger le dictionnaire de villes quelque part, vu que vous avez déjà appelé conserver dans la méthode init. Map dict ne publiera une fois votre citydictionary qu'une fois qu'il est auto-libéré, mais n'annulera pas la retenue que vous avez effectuée dans la méthode init.

Vous devriez essayer de vérifier vos autres méthodes pour une déclaration de version dans votre dictionnaire, ou demander à l'analyseur statique de vous le dire.

+0

Merci pour votre commentaire. Voyez ma réponse à ce qui l'a causé (complètement ma faute). Comment utilise-t-on un analyseur statique? J'utilise généralement la configuration 'Fuites' sur les Instruments. –