Timer et pauses
muqaddar
Administrateur
Soit un timer avec repeat à YES et un retain.
Soit une méthode.
Je souhaite faire faire une pause à mon timer tant que quelquechose n'est pas fini d'éxécuter ds la méthode.
Je pensais faire un invalidate pour la pause, ensuite un fire pour le relancer. La pause marche mais pas le relancement, invalidate détruit le timer d'après la doc.
Je décide donc d'appeller la première méthode qui lance le timer : [self declencheTimer], ... sauf que le premier timer n'a pas été releasé... pas glop. Si je release le premier timer apr!s le invalidate, ça plante...
Si vous avez pas tout compris, voici un peu de code :
et ds la méthode qui doit stopper et relancer le timer
Soit une méthode.
Je souhaite faire faire une pause à mon timer tant que quelquechose n'est pas fini d'éxécuter ds la méthode.
Je pensais faire un invalidate pour la pause, ensuite un fire pour le relancer. La pause marche mais pas le relancement, invalidate détruit le timer d'après la doc.
Je décide donc d'appeller la première méthode qui lance le timer : [self declencheTimer], ... sauf que le premier timer n'a pas été releasé... pas glop. Si je release le premier timer apr!s le invalidate, ça plante...
Si vous avez pas tout compris, voici un peu de code :
- (void)declencheTimer <br />{<br />timer = [[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(check:) userInfo:nil repeats:YES] retain];<br />[timer fire];<br />}
et ds la méthode qui doit stopper et relancer le timer
<br />if (comptage < [newArray count]) {<br />Â Â if ([timer isValid]==YES) {<br />Â Â Â [timer invalidate]; <br />Â Â }<br />}<br />else {<br />Â Â [self declencheTimer]; <br />}<br />
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
edit:
... au lieu d'utiliser un timer
Merci cBrandt, je me tue à le lui suggérer ::)
Je vois pas le rapport entre le performSelector qui ne se répète pas Hervé et mon Timer à YES !!!
Stops the receiver from ever firing again and removes it from any run loops.
De plus, si j'enlève le retain, il n'est plus reconnu pour l'invalider.
Je te propose de ruser un peu avec un bool (nommé timerState par exemple) que tu déclares dans ton fichier d'interfaçage puis :
Je te déconseille l'usage de multiples timer chacun devant tourner 16 fois puis être invalidés. ça risque de devenir le foutoir tous ces timers invalidés qui trainent encore dans ta runLoop
A la place tu peux (si on en reste à ton précédent exemple de ta méthode appelée par notification) devant boucler 16 fois avec 0.04 de pause:
Tu as mélangé deux sujets en même temps ClicCool.
Les timers qui doivent se répéter 16 fois, c'est pour un autre usage que celui là !
Néanmoins ton exemple ici pourra m'être utile je pense.
Merci.
Maintenant, dans mon cas, je ne peux remplacer le timer, sa répétition étant infinie. Ou alors il faut bidouiller un truc peut-être.
Voilà mon code simplifié :
[tt]- (id)init
{
if (self=[super init]) {
[self performSelector: @selector(declencheMailsTimer) withObject:nil afterDelay: 2];
}
return self;
}
- (void)dealloc
{
[mailsTimer release];
[super dealloc];
}
- (void)declencheMailsTimer
{
mailsTimer = [[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(checkMails userInfo:nil repeats:YES] retain];
[mailsTimer fire];
}
- (void)checkMails:(NSTimer*)timer
{
//blocage du timer
if (comptageMails < [newMailsArray count]) {
if ([mailsTimer isValid]==YES) [mailsTimer invalidate];
}
//relancer le timer
else {
[self performSelector: @selector(declencheMailsTimer) withObject:nil afterDelay: 2];
}
}[/tt]
Le problème étant toujours le même : si je mets un release dans le dernier else sur le timer, il plante... si je ne le mets pas, j'ai une fuite mémoire, avant de le relancer. Je comprends pas pourquoi il n'est pas retenu et reconnu si je ne mets pas ce retain en haut... :why?:
Tu peux pas tout simplement ne pas utiliser de timer du tout ?
(je le sens pas le coup du timer invalidé puis réactivé ...)
Et dans le cas présent remplacer la condition
if (16 tours)
par:
if (continue)
avec un simple flag continue à vrai ou faux ?
Comme ça quand tu veux interrompre le processus tu mets le flag à Faux.
Et quand tu veux le relancer tu le mets à Vrai et tu "amorce" en appelant la méthode une première fois.
un Timer est retenu par la runLoop.
Mais quand tu l'invalide rien ne garanti que la runLoop le retienne.
Mais surtout le timer release alors son userInfo et sa cible.
Je vais essayer comme tu dis.
Tient au fait , j'ai testé ça :
if ([mailsTimer retainCount]==1)
mais ça a pas l'air efficace, j'ai le droit ?
Vire ce timer !!
Je me suis servi de sa première soluce du post précédent pour un autre endroit où je n'ai besoin que de 16 répétitions de méthodes comme dit plus haut.
Belle galère (des méthodes à rebalancer ds le thread principal), mais merci à vous !
alex
Le premier, mailsTimer, égrenne les 5 premières secondes, puis on le retire de la runloop, ensuite, le second, waitingTimer, est lancé, puis égrenne les 5 secondes suivantes, ensuite on le retire de la runloop, puis on relance le cycle avec mailsTimer.
Il est vrai que la méthode isValid produit un plantage curieux, je ne sais pas pourquoi, mais je l'ai remplacé par un bool, qui ne sert pas a grand chose dans le cas actuel, mais qui est là pour le principe également pour d'éventuels tests.
[Fichier joint supprimé par l'administrateur]