2010-11-14 2 views
-1

J'ai un problème étrange mais je suis tout à fait sûr, pour vous ce n'est pas. Si c'est le cas, aidez-moi s'il vous plaît ou expliquez. J'ai un tableau de 39 UIImages qui seront utilisés pour animer UIImageView. et après avoir joué l'animation, la mémoire ne se libère pas.Étrange problème de libération

- (void)viewDidLoad { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 
    NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38]; 

    for (int i=1; i<=39; i++) { 
     NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"]; 
     UIImage *image = [[UIImage alloc]initWithContentsOfFile:path]; 
     [path release]; 
     [actionArray addObject:image]; 
     [image release]; 
     NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]); 
    } 
    imageView.animationImages = actionArray; 
    imageView.animationDuration = 4.0; 
    imageView.animationRepeatCount = 1; 
    [imageView startAnimating]; 
    NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]); 
    [actionArray release]; 
    [pool drain]; 
    [imageView release]; 
    [self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0]; 
    [super viewDidLoad]; 
} 

-(void)playAnimation2{ 
    if ([imageView isAnimating]) { 
     [imageView stopAnimating]; 
    } 
    NSLog(@"RetainCount ImageView %d",[imageView retainCount]); 
} 

aucune fuite n'a été découverte mais la quantité de mémoire allouée est toujours de 24 mb.

ou ce n'est pas si nécessaire?

EDIT:

Désolé, ma faute. En raison de nombreux changements de mon code, je me suis perdu. Après analyse, je l'ai! Merci beaucoup!

Le code est:

- (void)viewDidLoad { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; 
    NSMutableArray* actionArray = [[NSMutableArray alloc]initWithCapacity:38]; 

    for (int i=1; i<=39; i++) { 
     NSString* path = [[NSBundle mainBundle]pathForResource:[NSString stringWithFormat:@"bg_Level1_%.4d", i] ofType:@"png"]; 
     UIImage *image = [[UIImage alloc]initWithContentsOfFile:path]; 
//  [path release]; 
     [actionArray addObject:image]; 
     [image release]; 
     NSLog(@"path rc %d image %d", [path retainCount], [image retainCount]); 
    } 
    imageView.animationImages = actionArray; 
    imageView.animationDuration = 4.0; 
    imageView.animationRepeatCount = 1; 
    [imageView startAnimating]; 
    NSLog(@"RetainCount ActArr %d ImageView %d", [actionArray retainCount], [imageView retainCount]); 
    [actionArray release]; 
    [pool drain]; 
    [self performSelector:@selector(playAnimation2) withObject:self afterDelay:5.0]; 
    [super viewDidLoad]; 
} 

-(void)playAnimation2{ 
    if ([imageView isAnimating]) { 
     [imageView stopAnimating]; 
    } 
    [imageView removeFromSuperview]; 
    imageView.animationImages = nil; 
    NSLog(@"RetainCount ImageView %d",[imageView retainCount]); 
} 

Le problème était avec [path release];

+0

-1 Parce que votre code ne fonctionne plus du tout. Il se bloque tout de suite parce que vous libérez * path *. Afficher le code réel. Edit: Ok, ça ne plante pas directement, mais ça * va * planter quand l'image sera libérée. – Eiko

+0

Comment puis-je vous envoyer l'ensemble du projet? La chose la plus drôle est que rien ne se brise. – 0xDE4E15B

+0

Bien sûr, il ne plante pas, car vos images ne sont pas libérées - d'où votre problème. – Eiko

Répondre

6

Il y a pas mal de choses avec ce code. C'est une merveille qu'il court du tout.

Première:

Ne pas utiliser -retainCount.

Le nombre absolu de rétention d'un objet n'a pas de sens.

Vous devez appeler release exactement le même nombre de fois que vous avez provoqué la conservation de l'objet.Pas moins (sauf si vous aimez les fuites) et, certainement, pas plus (sauf si vous aimez les accidents). Pour plus de détails, voir le Memory Management Guidelines.


Maintenant, quelques-uns des problèmes:

  • vous a demandé si vous avez besoin de vider le tableau, puis dit array = nul; ... ne fonctionne pas. Définir une référence de tableau à zéro ne fait rien au tableau; ne le libère pas ou ne le vide pas.

  • vous overreleasing path

  • vous chargez une série d'images, coller « em dans un tableau, et il n'y a rien dans ce code qui libère le tableau (ou le vider). Que votre application continue d'utiliser la mémoire et montre qu'aucune fuite ne sonne comme un comportement correct.

  • Pourquoi lancez-vous imageView? Il n'y a rien dans ce code qui implique que vous l'avez conservé et, même s'il a été conservé via un autre mécanisme (IB?), Ce serait un endroit vraiment étrange pour le libérer.

+0

+1 tu sais, j'aurais juré que j'ai vu exactement la même réponse avant ...;) –

1

Je pense que vous devez supprimer tous les objets du tableau pour que cela fonctionne. Essayez de supprimer les objets de la matrice, puis la matrice une fois que vous en avez fini avec eux.

+0

a tenté de array = nil; imageView = nil; mais rien ne se passe. la mémoire allouée est toujours 23 mb. Des idées? – 0xDE4E15B

1

Vous libérez imageView sans le conserver n'importe où, il y a probablement quelque chose d'autre avec votre code. Il semble cependant que imageView soit retenu par un autre objet (très probablement le superview), qui le garde en mémoire. Cela permettra également de conserver le tableau d'images en mémoire.

Si vous n'avez pas besoin imageView plus, le retirer de son parent avec [imageView removeFromSuperview];

+0

imageView est créé avec IB. synthétisé et publié dans dealloc. et toujours pas d'amélioration. Si vous avez du temps libre et que vous désirez aider, je peux vous envoyer ce code par courriel. – 0xDE4E15B

+0

Je comprends, mais vous le publiez aussi dans viewDidLoad, donc votre dealloc pourrait tomber en panne! Si vous voulez juste libérer de la mémoire, un 'imageView.animationImages = nil;' après l'arrêt de l'animation pourrait aider. – FRotthowe

+0

dealloc ne plante pas. et sans libérer dans viewDidLoad le même résultat. Peut-être que je me trompe - après avoir supprimé l'imageView et le tableau, la mémoire sera libérée? n'est-ce pas? Essayé imageView.animationImages = nil et le même résultat reste. – 0xDE4E15B

1

Comme nous l'avons déjà résolu ici: releasing problems

Set imageView.animationImages = nil;

, vous devez également supprimer le [path release]; ou il va planter.

Le Memory Management Guide est un point de départ essentiel.

ModifierJamais ne dépend de la propriété retainCount!

Éditer 2 Libérer imageView dans cette méthode est clairement un bug aussi bien!

+0

Le Guide que j'ai lu et que je fais, comme je le pense, d'une manière correcte. étrange, mais le rien se bloque avec [libération du chemin]; D'accord. mais pourquoi Allocations Instrument me montre que j'ai encore 24mb utilisé? – 0xDE4E15B

+0

Man, avez-vous inséré le imageView.animationImages = nil; à vous jouerAnimation2? – Eiko

+0

Oui, c'était là, mais je ne sais pas ce qui s'est passé, mais après avoir supprimé tout ça maintenant ça marche! Merci – 0xDE4E15B