Rotation d'image se bloque

Bonjour à  vous.



Mon but est simple, mais il semblerait que graphiquement un problème survient.

J'ai un NSToolBarItem (Nom : majItem) dans lequel une image est présente. Le principe est de mettre en mouvement l'image par une rotation.

Cela fonctionne, hors j'ai une boucle qui permet la rotation toutes les 500ms mais on dirait que le graphisme ne suite pas :
<br />
NSAutoreleasePool *poolMAJ = [[NSAutoreleasePool alloc]init];<br />
   <br />
    double rotationDeg = 20.0;<br />
   <br />
    //Recuperation Image et Taille<br />
    NSImage *origin = [NSImage imageNamed:@&quot;MAJ1.png&quot;];<br />
    NSSize imageSize = [origin size];<br />
    NSImage *rotateImage = [[NSImage alloc] initWithSize:imageSize];<br />
   <br />
    //Définition du centre de l&#39;image (coordonnées)<br />
    NSPoint center = NSMakePoint(imageSize.width / 2.0, imageSize.height / 2.0);<br />
   <br />
    NSAffineTransform *transform = [NSAffineTransform transform];   <br />
   <br />
   <br />
    //Lancement du traitement<br />
    while(YES)<br />
    {<br />
	    [rotateImage lockFocus];<br />
	    [transform translateXBy:center.x yBy:center.y];<br />
	    [transform rotateByDegrees:rotationDeg];<br />
	    [transform translateXBy:-center.x yBy:-center.y];<br />
	    [transform concat];<br />
	   <br />
	    //Prise ne charge des modifications<br />
	    [origin drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];<br />
	    [rotateImage unlockFocus];<br />
   <br />
	    //Changement de l&#39;image<br />
	    [majItem setImage:rotateImage];<br />
	   <br />
	   <br />
	    if(rotationDeg == 360.0)<br />
		    rotationDeg = 20.0;<br />
	    else<br />
		    rotationDeg = rotationDeg + 20.0;<br />
	   <br />
	    NSLog(@&quot;degres rotation : %f&quot;,rotationDeg);<br />
	    [NSThread sleepForTimeInterval:0.5];<br />
    }<br />
    [poolMAJ release];<br />
    [NSThread exit];<br />
Le tout est dans un thread.



Je ne comprend pas l'erreur (qui doit être une belle erreur de débutant image/crazy.gif' class='bbc_emoticon' alt=' B) ' /> )

Si quelqu'un à  une idée...



Merci.

Réponses

  • MalaMala Membre, Modérateur
    Je commencerais par faire le setImage dans le main thread via "- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait" car je doute que ton item soit thread safe.
  • MalaMala Membre, Modérateur
    Heu, un doute me hante. Le code que tu mets tu l'exécute bien dans un thread à  part? Car sinon, effectivement ça va pas fonctionner. Dans ce cas, il te faut un faire un "display" dans ta boucle sinon ton item va jamais se mettre à  jour pour ton test.
  • Bonjour,



    Merci de tes réponses, je lance mon thread par un detachNewThreadSelector:

    Ma rotation est seulement prise en compte lorsque while n'est pas présent

    Je vais explorer tes solutions image/smile.png' class='bbc_emoticon' alt=':)' />
  • cocoacola71cocoacola71 Membre
    mars 2012 modifié #5
    Bon, le display fonctionnait très bien image/smile.png' class='bbc_emoticon' alt=':)' />

    Mais maintenant j'ai Exc-bad-access sur ma ligne:
    [mafenetre display];<br />
    




    Par contre et ce que je ne comprend pas, la rotation est parfois lente et parfois très rapide!

    Modif : Cela venait des mon angle maximum pour ce qui concerne la lenteur et la rapidité de la rotation
  • Tout bien réfléchit display n'est pas la méthode souhaitée

    L'erreur provient du chargement du webview, hors si j'utilise constamment display cela me produit des erreurs lorsque je navigue sur l'application.

    Le mieux pour moi serait de rafraà®chir directement NSToolBarItem, cela est possible??



    Merci
  • MalaMala Membre, Modérateur
    Tous les refresh graphiques doivent être réalisés dans le main thread d'où le bad access. Soit un truc du genre:


    [majItem performSelectorOnMainThread:@selector(display) withObject:nil waitUntilDone:YES];


    En cas, un setNeedsDisplay doit suffire.


    'cocoacola71' a écrit:


    L'erreur provient du chargement du webview, hors si j'utilise constamment display cela me produit des erreurs lorsque je navigue sur l'application.


    Quelle webview?
  • Mon .xib comporte plusieurs éléments tels que un Webview une NSToolBar (bien garnis) et d'autres...

    Et lorsque j'utilise mon webiew ou d'autre élément cela ralentit mon thread et lui fait perdre le cours de son exécution.

    Par exemple, j'incrémente de 1 degré ma rotation (Mon NSLog m'affiche chaque degrés), hors lorsque j'utilise mon webview ou un autre élément il m'arrive d'incrémenté de 8 degrés d'un coup ou même de revenir en arrière.

    Pourtant ma boucle est clair :
    <br />
    while(YES)<br />
        {<br />
    		    [rotateImage lockFocus];<br />
    		    [transform translateXBy:center.x yBy:center.y];<br />
    		    [transform rotateByDegrees:rotationDeg];<br />
    		    [transform translateXBy:-center.x yBy:-center.y];<br />
    		    [transform concat];<br />
    		  <br />
    		    //Prise ne charge des modifications<br />
    		    [origin drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeCopy fraction:1.0];<br />
    		    [rotateImage unlockFocus];<br />
      <br />
    		    //Changement de l&#39;image<br />
    		    [majItem setImage:rotateImage];<br />
    		  <br />
    		  <br />
    		    if(rotationDeg == 45.0)<br />
    				    rotationDeg = 1.0;<br />
    		    else<br />
    				    rotationDeg = rotationDeg + 1.0;<br />
    		  <br />
    		    NSLog(@&quot;degres rotation : %f&quot;,rotationDeg);<br />
    		    [NSThread sleepForTimeInterval:0.5];<br />
        }<br />
    
  • Faire le setImage dans le main thread, normalement un setNeedsDisplay n'est pas nécessaire.



    D'autre part:



    /color][color=#660066]NSThread[/color][color=#000000] [/color][color=#000088]exit[/color][color=#666600;



    est inutile et dangereux !

    Le thread est tué au retour de la méthode main.
  • cocoacola71cocoacola71 Membre
    mars 2012 modifié #10
    Mais si je fait le setImage dans le main, cela ne risque pas de ralentir mon application? voir même la figer?
  • MalaMala Membre, Modérateur
    'mpergand' a écrit:


    Faire le setImage dans le main thread, normalement un setNeedsDisplay n'est pas nécessaire.


    C'est ce qu'il me semblait aussi.



    J'ai l'impression que c'est le main thread qui sature au niveau rafraichissement avec la webview.


    'cocoacola71' a écrit:


    Mais si je fait le setImage dans le main, cela ne risque pas de ralentir mon application? voir même la figer?


    Non, l'image tu l'as calculé dans ton thread. Le setImage ne va faire que la stocker et taguer la vue comme étant à  rafraà®chir.
  • cocoacola71cocoacola71 Membre
    mars 2012 modifié #12
    J'ai donc inclus dans mon thread :
    [majItem performSelectorOnMainThread:@selector(setImage:) withObject:rotateImage waitUntilDone:YES];
    


    et donc supprimer la ligne :
    [majItem setImage:rotateImage];
    


    Cela fonctionne correctement image/smile.png' class='bbc_emoticon' alt=':)' /> hors lorsque j'utilise mon webview mon thread perd le cours de son exécution et fait n'importe quoi.

    Il saute des incrémentation ou revient en arrière... Ma rotation est horrible image/crazy.gif' class='bbc_emoticon' alt=' B) ' />
  • MalaMala Membre, Modérateur
    Yep, la webview (ou plutôt son contenu) doit monopoliser le thread principal pour son rafraichissement. Du coup, ton thread fait son job mais le refresh n'est pas effectué en temps et en heure. D'où ma proposition précédente de lancer un display dans le thread, juste après le setImage...


    [majItem performSelectorOnMainThread:@selector(setImageimage/smile.png' class='bbc_emoticon' alt=':)' /> withObject:rotateImage waitUntilDone:YES];

    [majItem performSelectorOnMainThread:@selector(display) withObject:nil waitUntilDone:YES];


    Du coup, tu ne laisses pas le choix au main thread. Il doit afficher l'image immédiatement. C'est le seul moyen d'améliorer les choses mais je ne sais pas si ce sera suffisant en terme de fluidité de rendu.
  • J'ai donc rajouté la ligne "display" mais malheureusement le résultat semble toujours problématique.
Connectez-vous ou Inscrivez-vous pour répondre.