2009-03-15 7 views
0

Je charge simplement un plist dans un dictionnaire temporaire pour initialiser mon modèle de données. Malheureusement, cette seule ligne de code ci-dessous entraîne une fuite cohérente tout au long du cycle de vie de l'application, conformément aux instruments. Les objets qui ont fui étant NSCFString et GeneralBlock sur un Malloc et la bibliothèque responsable étant Foundations.NSDictionary fuite sur iPhone et graphe de référence d'objet

Mes deux questions pour les yeux expérimentés:

  1. que je fais quelque chose d'étrange à déclencher ce? J'ai essayé de l'entourer dans le bloc autorelease mais cela n'a eu aucun effet.
  2. Existe-t-il un moyen d'imprimer la liste des références d'objet d'un objet suspect pour obtenir un aperçu du processus d'orphelinat d'objet.

Leaking Ligne:

NSDictionary *tempDict = [NSDictionary dictionaryWithContentsOfFile: 
          [[NSBundle mainBundle] 
           pathForResource:resourceName 
           ofType:@"plist"]]; 

totalChapters = [[tempDict objectForKey:@"NumberOfChapters"] intValue]; 
chapterList = [[NSMutableArray alloc] initWithCapacity: totalChapters]; 
[chapterList addObjectsFromArray:[tempDict objectForKey:@"Chapters"]]; 
+0

Peut-être que vous avez juste besoin de définir 'tempDict = nil' une fois que vous n'en avez pas besoin. –

Répondre

2

Il semble que vous pourriez avoir une fuite sur cette ligne:

[[NSMutableArray alloc] initWithCapacity: totalChapters]; 

Si cet objet est pas libéré, puis tous les objets que vous ajoutez à cela gagné ne sera pas publié non plus


Modifier (car il est trop long pour un commentaire):

Les instruments vous indiquent où la mémoire a été allouée, mais pas pourquoi elle est toujours conservée. Lorsque NSDictionary charge le contenu d'un fichier, il doit créer un objet pour chaque élément qu'il charge. Si l'on récupère plus tard un objet en utilisant objectForKey:, retain et en oubliant à release, une fuite sera signalée. L'instruction dictionaryWithContentsOfFile sera mise en cause car elle a effectué l'allocation. Je suis d'accord avec le débogage fantôme de Don. Très probablement, vous n'avez pas publié le vieux chapterList lorsque vous lui attribuez la deuxième fois.

+0

Le problème est dans la première ligne: NSDictionary * tempDict ... que j'utilise comme un espace temporaire pour charger plusieurs plists pendant le cycle de vie de l'application. Je m'attends à ce que tempDict soit libéré dans le cadre du pool car je ne l'attribue pas explicitement. L'objet que vous avez pointé sont des ivars qui sont libérés. –

+0

Si une valeur a déjà été affectée à chapterList, vous devez [release release chapterList] avant de lui assigner un nouvel objet. –

+0

Ma réponse est trop longue pour un commentaire, alors j'ai modifié :) – rpetrich

0

Je libère tous les trucs alloués dans la méthode dealloc de cette classe. La ligne TROUBLED ci-dessous est appelée à plusieurs reprises dans chaque alloc pour m'aider à charger de nouveaux chapitres basés sur la sélection de l'utilisateur.

NSDictionary * tempDict = [Dictionnaire NSDictionaryWithContentsOfFile: [[NSBundle mainBundle] pathForResource: resourceName ofType: @ "plist"]];

Puisque j'utilise la méthode de commodité sur NSDictionary je n'ai rien à Dealloc. Mais l'instrument pointe vers cette ligne particulière en tant que source de fuite via un Malloc. TempDict est juste un espace de travail pour un dictionnaire pour charger une plist et init les ivars.

-1

Le bloc autorelease affecte uniquement les objets placés dans le pool de libération automatique. Donc, tempDict est placé dans le pool autorelease, mais pas totalChapters.Si vous souhaitez utiliser la piscine autorelease vous voulez, soit:

[[[NSMutableArray alloc] initWithCapacity: totalChapters] autorelease];

ou ne pas utiliser la piscine autorelease et utilisation:

[[NSMutableArray alloc] initWithCapacity: totalChapters]
puis
[totalChapters release]

Il est recommandé d'éviter le pool d'autorelease sauf si nécessaire.

Questions connexes