[obj-c] NSTimer qui target self et retain cycles
colas_
Membre
Bonjour,
j'ai enfin trouvé ma fuite de mémoire !!
J'ai un View Controller qui sa méthode d'initialisation fait :
[NSTimer scheduledTimerWithTimeInterval:kTimeBeforeUpdatingTheBlurredView
target:self
selector:@selector(updateBlurredView)
userInfo:nil
repeats:YES] ;
Mon VC n'est alors jamais désavoué. Je pense que c'est parce que :
1) le timer retient self
2) le timer, qui est en mode repeat, est retenu par NSLoop
Du coup, self est toujours retenu.
J'ai vu une solution sur SO, qui consiste à créer un proxy pour l'objet à retenir :
[...]
@implementation BTWeakTimerTarget
{
__weak target;
SEL selector;
}
[...]
- (void)timerDidFire:(NSTimer *)timer
{
if(target)
{
[target performSelector:selector withObject:timer];
}
else
{
[timer invalidate];
}
}
@end
Je pense qu'il s'agit d'un problème classique alors je voulais avoir vos lumières !!!
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
PS : une autre solution pour moi serait
-> je peux invalider mon timer et le relancer dans viewWillApper et viewWillDisappear
-> dans ce cas, mon timer doit être une @property (weak), car elle est retain par le NSRunLoop
-> Je le crée (et la launche) dans -viewWillApper et l'invalidate dans -viewWillDisappear
Est-ce que j'ai tout bon ?
Merci !
PPS : L'avantage de la première solution est qu'elle marche tout le temps, pas que pour les VC qui ont des méthodes viewWillAppear or Disappear
Sur mon projet actuel, j'ai dû créer mon propre timer basé sur GCD pour cette raison, mais c'est un cas très particulier; en général tu maà®trises assez le cycle de vie de la target pour pouvoir invalider le timer.
Oui c'est un très grand classique. Félicitations, tu as trouvé le piège.
Les newbies qui font confiance aveugle à ARC se font d'autant plus facilement avoir qu'il ne réfléchissent pas à la gestion mémoire.
Moi qui n'ai suivi tous les épisodes, cette fuite mémoire apparaissait dans Instruments/Memory Leak ?
C'est vrai qu'en y réfléchissant un peu, cela devrait poser quelques problèmes mémoires.
Sur l'application du boulot actuelle (Legacy code), je me demande s'il n'y a pas ce soucis. Je sais qu'un de mes collègue a fait pas mal de clean ces derniers temps niveau gestion mémoire, mais je vais vérifier que celui-ci n'est pas présent, vu qu'elle est assez lourde et qu'il reste sûrement quelques trucs à améliorer.
L'info importante qui n'est pas dans la doc de la classe mais dans "Using Timers"...
Source: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Timers/Articles/usingTimers.html#//apple_ref/doc/uid/20000807-CJBJCBDE
Des outils comme Build&Analyze ou l'app fauxpas signalent-ils ce problème ?
Ce n'est pas un problème mais un fait fonctionnel. Il n'y a aucun bug derrière si ce n'est la méconnaissance du développeur qui l'emploie.
À noter ce pod qui gère un timer alternatif qui ne retain par son target !
https://github.com/mindsnacks/MSWeakTimer