2010-11-22 8 views
1

Dans le code ci-dessous, PersonListArray est un NSMutableArray et j'obtiens la liste des personnes de la DB sqlite et je l'ajoute à mon tableau.fuite de mémoire lors de l'ajout d'objets à nsarray

Person* tmpPerson = [[Person alloc] init]; 
tmpPerson.personName = @"Mike"; 
tmpPerson.personEmail = @"[email protected]"; 

[PersonListArray addObject:tmpPerson]; 
[tmpPerson release]; 

Même si je suis libérer l'objet Personne ici, son donnant une fuite de mémoire que je devine est dû au tableau contenant un nombre de référence. J'utilise le tableau ailleurs dans le programme et je le libère à coup sûr.

Quelle est la meilleure pratique pour créer de nouveaux objets pour un tableau et ne pas rencontrer ce problème?

Dans la méthode dealloc où je libère le tableau

-(void) dealloc{ 
    [PersonListArray release]; // this contains the numerous Person objects 
    [super dealloc]; 
} 

dois-je les libérer manuellement comme celui-ci à la place?

-(void) dealloc{ 

    for (int i = 0; i<PersonListArray.count;i++) 
    { 
    Person * tmpPerson = [PersonListArray objectAtIndex:i]; 
    [tmpPerson release]; 
    } 

    [PersonListArray release]; 
    [super dealloc]; 
} 
+0

Voici encore du code pour obtenir une meilleure image ... @interface Personne: NSObject { \t NSString * personName; \t NSString * personMobile; \t NSString * personEmail; \t } @property (nonatomic, retain) NSString * nomPersonne, * personEmail, * personMobile; – ArdenDev

Répondre

0

Votre code, tel qu'il a été initialement implémenté, est correct. Un tableau conserve les objets ajoutés et les libère lorsqu'ils sont supprimés du tableau ou lorsque le tableau est désalloué. Pas besoin de passer par le tableau vous-même.

Quels moyens utilisez-vous pour détecter la fuite? Si c'est Instruments alors vous pouvez mal comprendre ce qu'il vous dit. Lorsqu'il détecte une fuite, il peut vous indiquer où la mémoire a été allouée pour la première fois. Il ne peut pas vous montrer quel objet est responsable de la fuite. Je devinerais donc que la méthode dealloc donnée n'est jamais appelée (parce que cet objet est divulgué) ou que quelqu'un d'autre conserve le tableau et ne le libère pas. Essayez de mettre un NSLog dans dealloc pour vous assurer qu'il se produit; En tant que test une fois exécuté, vous pouvez essayer de consigner PersonListArray après l'avoir relâché - si cela ne provoque pas une exception de mémoire, il est presque certain que quelqu'un d'autre l'a conservé. [SUPPRIMÉ: mon texte original "Essayez d'ajouter un NSLog de [PersonListArray retainCount] à votre dealloc pour déterminer quel est le cas."; voir commentaire de bbum ci-dessous]

La cause la plus fréquente de retenues accidentelles supplémentaires est @ property/@ sythesize propriétés qui sont conservées mais pour lesquelles une version correspondante n'est pas ajoutée à dealloc.

+0

J'utilise des instruments et c'est le même comportement sur l'appareil. la méthode dealloc est toujours appelée. si j'utilise l'objet <--> méthode de conversion de chaîne comme mentionné ci-dessus, les fuites disparaissent. C'est vraiment bizarre – ArdenDev

+0

Est-il possible que vous ayez négligé de libérer personName, personMobile et personEmail dans le dealloc de Person? – Tommy

+1

** N'utilisez pas retainCount à des fins de débogage **. Le nombre absolu de rétention d'un objet est un détail d'implémentation et peut ne pas être ce que vous attendez tout en se comportant correctement. – bbum

3

Le code que vous nous montrez est correct et ne contient aucune fuite. La dernière section est fausse, cependant, et serait le cas de votre programme de se bloquer parce que vous libérez Person objets que vous ne possédez plus.

+0

SO maintenant si j'essaye de convertir l'objet de personne dans une liste de chaîne et l'ajoute au tableau cela fonctionne et je ne reçois aucune fuite dans les instruments. Mais maintenant je vais devoir convertir chaque objet en chaîne et vice versa au moment d'accéder à l'objet à partir du tableau. – ArdenDev

0

Quelque part dans votre application, vous appelez probablement le [PersonListArray objectAtIndex:n] et le transmettez à d'autres parties de votre application. Une des autres parties de votre application est probablement fuit. Si vous utilisez des fuites, cliquez sur le "type de fuite" particulier, puis cliquez sur l'adresse mémoire, et il vous montrera l'historique alloc/free/retain/release/autorelease de cette adresse mémoire. Si vous activez la vue détaillée (Cmd-E, je pense), vous verrez également des traces de pile pour tous ces objets. Recherchez quelque chose qui fait une retenue mais pas une version correspondante. (C'est un peu difficile quand les choses sont conservées par plusieurs tableaux auto-libérés ...)