0

Instruments' Fuites me dit que ce UIImage fuit:Pourquoi cette fuite de mémoire? UIImage `cellForRowAtIndexPath:`

UIImage *image = [[UIImage alloc] initWithContentsOfFile:[imagesPath stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@.png", [postsArrayID objectAtIndex:indexPath.row]]]]; 

// If image contains anything, set cellImage to image. If image is empty, try one more time or use noImage.png, set in IB 
if (image != nil){ 
    // If image != nil, set cellImage to that image 
    cell.cellImage.image = image; 
} 
image = nil; 
[image release]; 

(cellule de classe (cellule de vue de tableau personnalisé) libère également cellImage dans la méthode dealloc).

Je n'ai pas la moindre idée de la raison pour laquelle il fuit, mais c'est certainement le cas. Les images sont chargées plusieurs fois dans une méthode cellForRowAtIndexPath:. L'image des trois premières cellules ne fuit pas (130px de hauteur, tout l'espace disponible).

Les fuites ne me donnent pas d'autre information qu'une UIImage allocated here in the code leaks.

Pouvez-vous m'aider à le comprendre? Merci :)

+0

Que utiliseriez-vous dans cette situation? Quelle est la différence entre ces deux: [[UIImage alloc] initWithContentsOfFile: ...]; et [UIImage imageWithContentsOfFile: ...] ;. Y a-t-il une différence? – Emil

Répondre

5

Le code que vous avez là serait correct si l'image était un @property. Vous pouvez libérer un @property en faisant self.property = nil en raison de la façon dont le setter fonctionne. L'accesseur libère l'ancien objet et définit l'ivar sur la valeur. Afin de résoudre ce problème, vous devez d'abord mettre [image release]. Qu'est-ce qui se passe ici, c'est que vous définissez l'image à zéro, puis vous faites essentiellement [nil release]. La vieille image flotte juste quelque part. Donc, pour résoudre ce problème procédez comme suit:

[image release]; 
image = nil; 
+0

Bonne explication. Merci. – Emil

+0

Oh, et à quoi bon mettre un objet libéré à «nil» de toute façon? – Emil

+0

La raison principale est que si vous étiez pour une raison quelconque, appelez une méthode, elle ne retournera pas comme EXC_BAD_ACCESS. Si vous envoyez un message à un objet publié, votre application plante avec EXC_BAD_ACCESS comme raison – rickharrison

3

Vous le définissez à nil avant d'appeler release. Donc, vous libérez nil au lieu de image.

Changement de:

image = nil; 
[image release]; 

à:

[image release]; 
image = nil; 
+0

Oh, je n'avais pas réalisé que ça pouvait causer une fuite ..! Merci :) – Emil

+0

Que utiliseriez-vous dans cette situation? Quelle est la différence entre ces deux: '[[UIImage alloc] initWithContentsOfFile: ...];' et '[UIImage imageWithContentsOfFile: ...];'. Y a-t-il une différence? – Emil

+1

Pas que je sache vraiment. Le 'imageWithContentsOfFile' est une méthode pratique. Il est donc responsable de libérer l'image. Si vous appelez alloc, vous êtes responsable. Vous pouvez lire à ce sujet dans le guide de gestion de la mémoire Apple ici: http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html –

0

peu de code binaire modification

UIImage *image = [[UIImage alloc] initWithContentsOfFile:[imagesPath 
     stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@.png", 
     [postsArrayID objectAtIndex:indexPath.row]]]]; 

if (image){ 
    cell.cellImage.image = image; 
    [image release];