Auto-arrêt d'un timer.

tabliertablier Membre
15:13 modifié dans API AppKit #1
Pour tester la présence du périphérique m600, j'utilise un timer comme ci dessous:
NSTimer      *isPresent ;
BOOL        present ;

- (void)metTimer
{
isPresent = [NSTimer scheduledTimerWithTimeInterval:0.5  target:self
      selector:@selector(testPresent)  userInfo:nil  repeats:YES];
}

- (void)testPresent
{
if ([o_m600  find_m600_device])
{ present = YES ;
[o_etat setStringValue:@m600 est connecté] ;
[isPresent invalidate] ;
}
else
{ if (!present) return ;
present = NO ;
[o_etat setStringValue:@m600 n'est pas connecté] ; } ;
}
Je souhaite que le timer se dé-valide de lui même si le m600 est connecté. J'ai donc mis le "invalidate" dans le callback. Je n'arrive pas à  trouvé dans la doc si j'ai le droit de faire ça!  Et si je n'ai pas le droit de faire ça, y a t-il une méthode pour le faire correctement?
Quelqu'un a une idée la dessus?

Réponses

  • ChachaChacha Membre
    juin 2010 modifié #2
    dans 1277929300:

    J'ai donc mis le "invalidate" dans le callback. Je n'arrive pas à  trouvé dans la doc si j'ai le droit de faire ça!  Et si je n'ai pas le droit de faire ça, y a t-il une méthode pour le faire correctement?
    Quelqu'un a une idée la dessus?

    A priori ça me semble bon. Je pense plutôt que si c'était interdit, ce serait précisé.

    [edit]
    Ah, à  l'instant je vois même dans la doc que c'est autorisé !
    "You can also invalidate a timer from the method it invokes. For example, the method invoked by the timer shown in “Initializing a Timer with a Fire Date” might look like this:" (cf: Timer programming topics, using Timers)
    [/edit]

    Dans ce genre de cas, si tu as un doute, tu peux essayer le performSelector:withObject:afterDelay: qui planifie le truc un peu plus tard dans la boucle événementielle. (qqchose comme [timer performSelector:@selector(invalidate) withObject:nil afterDelay:0])

    Profitons-en pour rappeler qu'un NSTimer fait un retain de sa target, donc qu'il ne faut pas compter sur le dealloc de cette même target pour faire un invalidate du timer. Il faut bien le faire manuellement avant, sous peine de fuite mémoire. C'est nul mais c'est comme ça :-)
  • AliGatorAliGator Membre, Modérateur
    juin 2010 modifié #3
    La méthode "-invalidate" de NSTimer ne fait que retirer le NSTimer de la RunLoop dans laquelle il a été schedulé, ce qui a pour effet :
    1) Qu'il ne se déclenchera plus à  partir de la prochaine RunLoop
    2) Qu'à  moins que tu aies fait un retain explicite (ce qui n'est pas ton cas dans ton code), le timer est détruit.

    En effet, "scheduledTimerWithInteral..." crée le timer et l'ajoute (le "schedule") dans la RunLoop, et c'est cette dernière qui retient le timer (retain implicite du Timer par la RunLoop), et qui va le relâcher (release implicite) quand le timer sera retiré de la RunLoop via un appel à  "invalidate".


    Donc pas de soucis, tu peux appeler "invalidate" dans la callback comme tu le fais dans ton code.

    Cependant deux petites remarques :
    • comme indiqué dans la doc, le @selector que tu utilises pour ton NSTimer doit avoir une signature du type [tt]- (void)timerFireMethod:(NSTimer*)theTimer[/tt], donc une méthode prenant un argument unique (qui sera le NSTimer ayant déclenché ladite méthode). Or ce n'est pas ton cas, il faut corriger ça (c'est juste un argument à  rajouter dans ta méthode, et un ":" à  rajouter dans ton @selector)
    • Du coup tu n'as pas besoin de déclarer ton NSTimer isPresent comme variable d'instance à  la limite : tu peux le créer dans ta méthode metTimer, sans l'assigner à  aucune variable, et l'invalider dans ta callback (puisque tu auras une variable locale " le paramètre de la méthode " pointant vers ledit timer du coup maintenant).
      Ce qui évite de plus de risquer d'utiliser le NSTimer "isPresent" par erreur après qu'il a été invalidé (et don releasé et détruit) " si tu n'as pas d'ivar pointant dessus, tu ne risques pas de l'utiliser à  mauvais escient.
      Si tu préfères garder l'ivar quand même, je te conseille " juste par mesure de précaution et par bonne habitude " de mettre alors cette variable isPresent à  nil juste après l'appel à  invalidate.


    [EDIT] Grillé par Chacha
  • ChachaChacha Membre
    juin 2010 modifié #4
    dans 1277932619:

    [EDIT] Grillé par Chacha

    ça doit faire un an que c'est pas arrivé.  :p
  • AliGatorAliGator Membre, Modérateur
    15:13 modifié #5
    :D Promis, le prochain je te le laisse alors :)
    Un petit digestif pour fêter ça ?
  • tabliertablier Membre
    15:13 modifié #6
        Ok, merci à  tous. Je vais retourner lire la doc car je suis sous 10.4 (je n'ai hélas pas le choix) et je n'ai pas trouvé la précision donné par Chacha.
    Pour le digestif, je suis partant!  :p
Connectez-vous ou Inscrivez-vous pour répondre.