Périodicité sans méthode

muqaddarmuqaddar Administrateur
22:41 modifié dans API AppKit #1
Salut,

Dans une boucle while toute bête qui affiche du texte, je voudrais mettre un délai de 5 secondes ente chaque passage dans la boucle.
Le timer ne me semble pas adapté ds mon cas
Disons que je veux juste faire une pause ds ma boucle.

<br />while (...) {<br />&nbsp; &nbsp;  afficheTexte;<br />&nbsp; &nbsp;  pause de 5 secondes le temps de le lire;<br />}


Quelle astuce utiliser ?
«1

Réponses

  • muqaddarmuqaddar Administrateur
    22:41 modifié #2
    Peut-être créer un timer ds la boucle avec un délai de 5 secondes et sans repeat ?
  • BruBru Membre
    22:41 modifié #3
    fais tout simplement un sleep(5), et le tour est joué !

    .
  • ClicCoolClicCool Membre
    mars 2005 modifié #4
    Salut oxitan,

    Si tu fais une boucle pour temporiser tu risque de figer l'appli dans la boucle ...

    Si un timer te sembles disproportionné, pourquoi ne pas terminer ta méthode par un:

    [self performSelector: @selector(maMethode:) withObject:nil afterDelay: 5];<br />
    


    [grilled] mais je suis pas le seul:
    dans 1110189152:

    tu peux utiliser :
    sleep(5);

    et cette option va figer ton appli dans la boucle sans permettre d'action utilisateur ...
  • amnesicamnesic Membre
    mars 2005 modifié #5
    tu peux utiliser :
    sleep(5);
    [Edit] Bru l'homme qui poste plus vite que son ombre 
  • muqaddarmuqaddar Administrateur
    22:41 modifié #6
    dans 1110189041:

    fais tout simplement un sleep(5), et le tour est joué !

    .


    Il apprécie pas du tout, et ça me plante tout. ;)

    @ClicCool : j'ai aucune méthode à  appeler.
  • ClicCoolClicCool Membre
    mars 2005 modifié #7
    dans 1110189378:

    @ClicCool : j'ai aucune méthode à  appeler.

    remplaces ta boucle par une méthode exécutant son contenu (1 fois seulement).

    <br />while (...) {<br />&nbsp; &nbsp;  afficheTexte;<br />&nbsp; &nbsp;  pause de 5 secondes le temps de le lire;<br />}
    


    devient:

    <br />-(void) maMethode {<br />&nbsp; &nbsp;  afficheTexte;<br />&nbsp; &nbsp;  [self performSelector: @selector(maMethode) withObject:nil afterDelay: 5];<br />}
    
  • BruBru Membre
    22:41 modifié #8
    dans 1110189378:

    dans 1110189041:

    fais tout simplement un sleep(5), et le tour est joué !

    .


    Il apprécie pas du tout, et ça me plante tout. ;)

    @ClicCool : j'ai aucune méthode à  appeler.


    Même en rajoutant #include <unistd.h> ?

    .
  • AntilogAntilog Membre
    22:41 modifié #9
    Je pense que clickCool proposait de rappeler la méthode qui avait initié la boucle (pour poursuivre le traitement après 5 secondes  ;) )

    Mais bon, peut-être que j'interprète mal  :brule:
  • AntilogAntilog Membre
    22:41 modifié #10
    Trop tard...

    Mais bon, j'avais à  peu près compris
  • muqaddarmuqaddar Administrateur
    22:41 modifié #11
    dans 1110189737:

    dans 1110189378:

    dans 1110189041:

    fais tout simplement un sleep(5), et le tour est joué !

    .


    Il apprécie pas du tout, et ça me plante tout. ;)

    @ClicCool : j'ai aucune méthode à  appeler.


    Même en rajoutant #include <unistd.h> ?

    .


    Pareil...

    J'ai essayé un timer, je pense que ça pourrait marcher, mais y'a un pb avec invocation :


    NSLog(@&quot;-----pause------&quot;);<br />				NSLog(@&quot;mailLine : %@&quot;, mailLine);<br />				NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:5 invocation:self repeats:NO];<br />				[timer fire];
    
  • amnesicamnesic Membre
    22:41 modifié #12
    dans 1110189378:

    Il apprécie pas du tout, et ça me plante tout. ;)

    Etrange ... c'est à  la compil que ca ne passe pas ? à  l'exécution ? un log du crash ?

  • ClicCoolClicCool Membre
    22:41 modifié #13
    dans 1110190719:


    J'ai essayé un timer, je pense que ça pourrait marcher, mais y'a un pb avec invocation :


    .../...<br />&nbsp; &nbsp; &nbsp; &nbsp;  invocation:self repeats:NO];
    



    invocation est un objet de type NSInvocation (fort puissant concept que celui là ).

    Tu sembles confondre avec la target, utilises alors la méthode: timerWithTimeInterval:target:selector:userInfo:repeats:
  • muqaddarmuqaddar Administrateur
    22:41 modifié #14
    Oui, j'ai réessayé :
    NSLog(@&quot;-----pause------&quot;);<br />				NSLog(@&quot;mailLine : %@&quot;, mailLine);<br />				NSTimer* timer = [NSTimer timerWithTimeInterval:5 target:self selector:nil userInfo:nil repeats:NO];<br />				[timer fire];
    


    et ça me renvoie :
    *** NSTimer discarding exception 'NSInvalidArgumentException' (reason '*** -[Controller methodSignatureForSelector:]: null selector') that raised during firing of timer with target 341e50 and selector '(null)'
  • amnesicamnesic Membre
    22:41 modifié #15
    Tu peux faire ta pause via "sleepUntilDate" sinon

    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval)5.0]];

    ...mais j'aimerais bien comprendre pourquoi "sleep" ne fonctionne pas chez toi .
  • ClicCoolClicCool Membre
    mars 2005 modifié #16
    dans 1110191763:

    Oui, j'ai réessayé :
    .../... selector:nil .../...
    


    et ça me renvoie :
    *** NSTimer discarding exception 'NSInvalidArgumentException' (reason '*** -[Controller methodSignatureForSelector:]: null selector') that raised during firing of timer with target 341e50 and selector '(null)'


    Ben oui si tu mets selector:nil, il te dit que selector est nil et qu'il aime pas ça du tout ;)
    Faut dire au timer quelle méthode il doit executer quand il se lance.

    (comme je te proposait de le faire plus simplement avec performSelector: ... )
  • mpergandmpergand Membre
    22:41 modifié #17
    nextEventMatchingMask:untilDate:inMode:dequeue:

    C'est la  méthode que j'utilise pour éviter l'apparition de la roue de la mort...

    Code Java, pas sûr que ça soit transposable directement en ObjC
    <br />public static void wait(double time)<br />		{<br />		NSApplication app=NSApplication.sharedApplication();<br /><br />		double time1=NSDate.currentTimeIntervalSinceReferenceDate();<br />		double time2;<br />		<br />		do	{<br />			app.nextEventMatchingMask(0xffffff,new NSDate(0.1,new NSDate()),NSRunLoop.DefaultRunLoopMode,false);<br /><br />			time2=NSDate.currentTimeIntervalSinceReferenceDate();<br />				<br />			}while((time2-time1)&lt;time);<br />				<br />	}<br />
    
  • muqaddarmuqaddar Administrateur
    22:41 modifié #18
    dans 1110191823:

    Tu peux faire ta pause via "sleepUntilDate" sinon

    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval)5.0]];

    ...mais j'aimerais bien comprendre pourquoi "sleep" ne fonctionne pas chez toi .


    Peut-être parce que j'appelle la méthode qui contient la boucle en question ds le awakeFromNib, qui plus est par un timer !!!

    Ds le awake :

    [code] mailsTimer = NSTimer scheduledTimerWithTimeInterval:15 target:self selector:@selector(checkMailsFromApp:) userInfo:nil repeats:YES] retain]; <br /> [mailsTimer fire]; [/code]<br /><br />[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval)5.0;
    me donne le même résultat que sleep(5);
  • muqaddarmuqaddar Administrateur
    22:41 modifié #19
    dans 1110191955:

    dans 1110191763:

    Oui, j'ai réessayé :
    .../... selector:nil .../...
    


    et ça me renvoie :
    *** NSTimer discarding exception 'NSInvalidArgumentException' (reason '*** -[Controller methodSignatureForSelector:]: null selector') that raised during firing of timer with target 341e50 and selector '(null)'


    Ben oui si tu mets selector:nil, il te dit que selector est nil et qu'il aime pas ça du tout ;)
    Faut dire au timer quelle méthode il doit executer quand il se lance.

    (comme je te proposait de le faire plus simplement avec performSelector: ... )



    C'est fou, il doit bien y avoir une solution sans créer de méthode en plus ! ;)
  • amnesicamnesic Membre
    22:41 modifié #20
    dans 1110192197:

    Peut-être parce que j'appelle la méthode qui contient la boucle en question ds le awakeFromNib, qui plus est par un timer !!!

    Je viens de tester ici dans cette configuration et cela ne pose pas de problème ... tu as quelque chose dans la consol log ? ca crash ? 
  • muqaddarmuqaddar Administrateur
    22:41 modifié #21
    Je reprends parce que c'est plus compliqué que prévu.

    Appel d'une méthode ds un timer toutes les 30 secondes
    - (void)awakeFromNib<br />{<br />	//checking des emails au lancement de l&#39;appli<br />	mailsTimer = [[NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(checkMailsFromApp:) userInfo:nil repeats:YES] retain];	<br />	[mailsTimer fire];	<br />}
    


    Puis la méthode :
    //controle des emails<br />- (void)checkMailsFromApp:(NSTimer*)timer<br />{<br />&nbsp; &nbsp;  while (eachMailLine = [enumerator nextObject]) {<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (eachTerm = [enumeratorDetailsDuMail nextObject]) {				<br />					mailLine=[[mailLine stringByAppendingString: eachTerm] stringByAppendingString: @&quot;&#092;n&quot;];<br />				}<br />				<br />				NSLog(@&quot;-----pause------&quot;);<br />				NSLog(@&quot;mailLine : %@&quot;, mailLine);<br />				NSTimer* timer = [NSTimer timerWithTimeInterval:5 target:self selector:nil userInfo:nil repeats:NO];<br />				[timer fire];<br /><br />			}<br />		}<br />}<br />
    


    Note : La pause de 5 secondes doit etre faite ds la première boucle while. J'ai enlevé le code qui ne vous sert pas.
  • ClicCoolClicCool Membre
    22:41 modifié #22
    dans 1110193430:

    Appel d'une méthode ds un timer toutes les 30 secondes

    Puis la méthode :
    //controle des emails<br />- (void)checkMailsFromApp:(NSTimer*)timer<br />{<br />&nbsp; &nbsp;  while (eachMailLine = [enumerator nextObject]) {<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (eachTerm = [enumeratorDetailsDuMail nextObject]) {		<br />				NSLog(@&quot;-----pause------&quot;);<br />			}<br />		}<br />}<br />
    


    Note : La pause de 5 secondes doit etre faite ds la première boucle while.


    Tu prends pas le risque que tout se téléscope là :

    Ta méthode d'épluchage des mails est appelée toutes les 30 seçondes et elle même fait une pause de 5 seconde à  chaque message ...
    S'il y a + de 6 mesages ça lui fait une pause > 30 seçondes et checkMailsFromApp va donc être appelée alors  qu'elle n'a pas finie  ???
  • muqaddarmuqaddar Administrateur
    22:41 modifié #23
    J'y ai pensé.

    1) je fais le test avec 2 mails seulement pour l'instant
    2) ensuite quand ça marchera je bidouillerai un truc avec une variable d'instance pour détruire le second timer et éviter le télescopage.

    Mais pour l'instant, ça foire, même avec 2 mails. :(
  • muqaddarmuqaddar Administrateur
    mars 2005 modifié #24
    Bon, merci pour votre aide.

    J'ai mis le timer principal dans le init à  la place du awakeFromNib et la plus de problème.
    Même avec un sleep(5) !

    Encore merci à  tous. :)


    EDIT : ça marche mais c'est super lent.
  • ClicCoolClicCool Membre
    22:41 modifié #25
    dans 1110202654:

    EDIT : ça marche mais c'est super lent.


    un peu comme si ton appli faisait des pauses successives de 5 sec ?  :P
    :)beta:
  • muqaddarmuqaddar Administrateur
    22:41 modifié #26
    Non !
    y'a la roue multicolore qui tourne irrégulièrement, c'est du au sleep ?
  • ClicCoolClicCool Membre
    mars 2005 modifié #27
    dans 1110206752:

    Non !
    y'a la roue multicolore qui tourne irrégulièrement, c'est du au sleep ?


    Il me semble que oui en effet  :(

    Si tu mets une boucle avec sleep dans le thread principal, le thread principal roupille et ton application avec ...

    Si ta boucle dormante est dans un autre thread alors ton appli devrait rester réactive.

    ET je crois bien que tu as mis ton sleep à  l'envers  ;D

    [EDIT] désolé, finalement j'ai pas pu résister  :P
  • muqaddarmuqaddar Administrateur
    22:41 modifié #28
    Ok.

    J'ai essayé la technique de amnesic, mais c pareil :
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval)3.0]];
  • ClicCoolClicCool Membre
    22:41 modifié #29
    dans 1110207498:

    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:(NSTimeInterval)3.0]];


    Oui en effet ce doit être pareil, le thread principal est endormis, la runLoop est là  encore shuntée et non parcourue et ton appli semble donc bloquée.
  • mpergandmpergand Membre
    22:41 modifié #30
    dans 1110206752:

    Non !
    y'a la roue multicolore qui tourne irrégulièrement, c'est du au sleep ?

    http://www.objective-cocoa.org/forum/index.php?topic=722.msg8033#msg8033

    ;D ;D
  • muqaddarmuqaddar Administrateur
    22:41 modifié #31
    Le java, c'est du charabia pour moi. ;)
    C'est tout à  l'envers... ou l'obj-C est tout à  l'envers... ;)

    La question est : est-ce qu'un timer dans un timer entraà®ne la roue de la mort ou la roue de la fortune ?
Connectez-vous ou Inscrivez-vous pour répondre.