tout d'abord désolé pour mon anglais :-) pas si bon.étrange fuite de mémoire dans la fenêtre: addSubView
J'ai une fuite de mémoire étrange avec le code suivant (code après l'explication). J'ai une classe, FLWaitingView. C'est une vue simple avec un indicateur d'attente (plus une vue avec arrière-plan), utilisé pour dire à l'utilisateur "attendre que les données soient chargées". Il a deux méthodes simples: montrer et rejeter. Dans la méthode show, je trouve la fenêtre principale de l'application et ajoute les sous-vues (la vue en attente et une vue en arrière-plan, avec différentes animations). Dans la méthode de rejet, je l'enlève de superview. Dans chaque spectacle, je vérifie que la vue n'est pas déjà visible en utilisant un booléen statique var (is_visible).
La chose étrange est ceci: Dans le rejeter la méthode, je l'utilise:
[self.view removeFromSuperview];
[self.waitingView removeFromSuperview];
pour enlever les deux vues de la fenêtre, pour les éviter à retenir. Ils sont correctement supprimés, je peux vérifier cela avec NSLog (pour cicle sur chaque sous-vue de la fenêtre). Mais, dans INSTRUMENTS, en utilisant la fonction "mark heap", je vois que dans chaque rechargement (nouvelle instance de FLWaitingView, puis show, puis rejeter) l'ancienne instance reste en mémoire et continue d'augmenter l'utilisation de la mémoire. est évidemment pas un problème du code d'appel, parce que je libère correctement l'objet:
//CALLING CODE
//customWaitingView is a property retained
self.customWaitingView = [[[FLWaitingView alloc]init]autorelease];
[self.customWaitingView show];
De plus, et je pense que c'est l'information la plus importante, si je déplace la dismission vue dans une autre méthode, appelée par un sélecteur, la fuite disparait !!!
Maintenant, je montre le "mauvais" code et, après, la "correction". Je voudrais comprendre pourquoi cela arrive.
- (void)show
{
if (!is_visible){
id appDelegate = [[UIApplication sharedApplication] delegate];
UIWindow *window = [appDelegate window];
self.waitingLabel.text = @"Attendere";
self.view.alpha = 1.0;
self.waitingView.alpha = 1.0;
[window addSubview:self.view];
[window addSubview:self.waitingView];
[self.waitingIndicator startAnimating];
self.view.frame = window.frame;
self.waitingView.center = window.center;
// "Pop in" animation for alert
[self doPopInAnimationWithDelegate:self];
// "Fade in" animation for background
[self doFadeInAnimation];
is_visible = YES;
} else {
NSLog(@"FLWaitingView %@ already visible, do nothing", self);
}
}
- (void)dismiss
{
[UIView beginAnimations:nil context:nil];
self.view.alpha = 0.0;
self.waitingView.alpha = 0.0;
[UIView commitAnimations];
[self.waitingIndicator stopAnimating];
//here is the problem
[self.view removeFromSuperview];
[self.waitingView removeFromSuperview];
is_visible = NO;
}
le code ci-dessus est le « mauvais », mais si j'ajoute
[self performSelector:@selector(alertDidFadeOut) withObject:nil afterDelay:0.5];
dans le rejeter la méthode et une nouvelle méthode (suppression de toute évidence le code redondant de rejeter la méthode):
- (void)alertDidFadeOut
{
//here the memory is correctly released
[self.view removeFromSuperview];
[self.waitingView removeFromSuperview];
is_visible = NO;
}
la mémoire est correctement libérée. Pourquoi ?????? Nous vous remercions à l'avance
Fabio
cela fonctionne aussi (pas de mémoire fuite), comme mon autre "workaroud", mais je ne comprends pas pourquoi :-). Quel est le problème dans le premier code? les vues semblent être correctement enlevées de la fenêtre principale ... mais pas libérées ... – LombaX
@LombaX: j'ai édité ma réponse avec quelques explications –
Merci beaucoup! Maintenant, je comprends :-) passer à l'animation en bloc !! – LombaX