2010-09-21 18 views
1

Lorsque j'analyse le code suivant avec des instruments, il fait état d'une fuite sur la variable imageName:NSString fuite même avec la libération au bon endroit (je suppose)?

//loadImagesFromPotatoesIndexesArray 
-(void) loadImagesFromPotatoesIndexesArray{ 

    //Load Textures from Disk 
    textures = [[NSMutableArray alloc] init]; 
    //NSArray *masks = [[NSArray alloc] initWithArray:mainDelegate.masksArray]; 

    for (int i = 0;i<[potatoesIndexesArray count];i++){ 

     int imageNumber = [[potatoesIndexesArray objectAtIndex:i]intValue]; 

     NSString *imageName = [[NSString alloc] initWithFormat:@"texture%d",imageNumber]; 

     UIImage *image = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:@"png"]]; 

     NSArray *pics = [[NSArray alloc] initWithObjects: 
         [self maskImage:image withMask:[mainDelegate.masksArray objectAtIndex:i]], 
         [self maskImage:image withMask:[mainDelegate.masksArray objectAtIndex:i]], 
         imageName, 
         nil]; 

     [textures addObject:pics]; 

     [image release]; 
     [imageName release]; 
     [pics release]; 
    } 
} 

[potatoesIndexesArray count] = 16, donc j'ai 16 fois que NSCFString ... Mais fuite moi le code respecte la gestion de la mémoire ... évidemment pas !!! Qu'est-ce que j'ai fait de mal?

+0

semble correct. Avez-vous testé sur votre appareil? Parfois, vous obtenez des «fausses» fuites lors de l'utilisation du simulateur. –

Répondre

0

Si pense que lorsque vous ajoutez imageName dans votre tableau les photos il le conserver ;-) (je pense que la réponse à votre question)

Mais, pourquoi fais-tu un alloc ici? Pourquoi ne pas faire quelque chose comme

[ NSString stringWithFormat:@"" ]
?

Bonne chance!

+0

Oui, si vous ajoutez quelque chose à un tableau, il sera conservé. Ce n'est pas la même chose que la fuite, car vous pouvez toujours y accéder via le tableau. –

+0

+ stringWithFormat va s'ajouter au pool autorelease. L'utilisation de -initWithFormat signifie que la chaîne peut être libérée bien avant que le pool autorelease soit drainé, ce qui économise de la mémoire. Je n'ai aucune idée si cela est critique pour ce morceau de code ou pas, mais il y a la raison d'utiliser -init ... over + string ... –

0

Ceci est un problème compliqué. Vous allouez l'imageName, de sorte que retainCount est 1, puis vous l'ajoutez dans un tableau, le nombre de retain est 2, lorsque vous relâchez imageName, le nombre de retenue est 1 à nouveau. Alors si vous libérez aussi le tableau de pics, tout ira bien. Mais votre tableau de photos est ajouté dans les textures, puis le pics est publié, donc vos photos retainCount est toujours 1. Et votre imageName est une fuite. Mais, si vous relâchez le tableau textures, tout ira bien

NSString *imageName = [[NSString alloc] initWithFormat:@"texture%d",imageNumber]; 

    NSArray *pics = [[NSArray alloc] initWithObjects: 
        [self maskImage:image withMask:[mainDelegate.masksArray objectAtIndex:i]], 
        [self maskImage:image withMask:[mainDelegate.masksArray objectAtIndex:i]], 
        imageName, 
        nil]; 

    [imageName release]; 
+1

Je vais devoir supposer qu'il s'occupe de libérer le tableau de textures correctement après l'utilisation il. Votre explication est éteinte, et pas pourquoi il voit la fuite. –

+0

Semble une explication raisonnable (et correcte) pour moi. –

+0

Le problème racine ne libère probablement pas le tableau de textures. Si le tableau textures est libéré, tout ce qu'il contient sera libéré (y compris le tableau pics, qui publiera imageName). –

3

Vous ne diffusons jamais le tableau « textures ». Il tient toujours tout.

1

À quelle fréquence loadImagesFromPotatoesIndexesArray est-il appelé dans votre code? Si elle est appelée plusieurs fois, toutes les valeurs du tableau d'origine seront divulguées, car vous ne publiez pas correctement textures avant de le remplacer par un nouveau tableau.

Si elle est appelé plus d'une fois, cela devrait faire l'affaire:

// load textures from disk 
[textures removeAllObjects]; 
//NSArray *masks = [[NSArray ... 

for (int i=0; ...