NSThread & NSProgressIndicator

Bonjour,



j'ouvre un nouveau sujet, voila la situation, j'ai une méthode qui est en charge de push vers des ViewController. Quand j'appel cette méthode, je me charge de l'appellé de manière synchrone.
<br />
[color=#401082]<br />
[color=#000000][[/color][color=#b41ca4]self[/color][color=#000000] [/color]performSelectorInBackground[color=#000000]:[/color][color=#b41ca4]@selector[/color][color=#000000](pushView:) [/color]withObject[color=#000000]:nil];[/color][/color][color=#401082]<br />
[color=#000000]
[/color][/color]

Du coup ce que j'aimerais bien c'est que vu que ma méthode est appelé de manière synchrone, j'aimerais en même temps pouvoir afficher un progressIndicator, qui est arrêté une fois arrivé dans la la nouvelle vue.


C'est possible ?

Réponses

  • AliGatorAliGator Membre, Modérateur
    juin 2012 modifié #2
    Alors, clairement, afficher un progressIndicator, ça veut dire manipuler l'interface graphique de ton application, or il est très important de savoir que seul le main thread a le droit de modifier l'UI d'une application. Tu ne dois pas manipuler d'objets de l'interface graphique (de UIView & co) dans un thread secondaire, la boucle de rendu des éléments à  l'écran étant forcément dans le thread principal et lui seul.



    Après, si tu avais une opération longue (genre algo de calcul) à  exécuter en tâche de fond, il est plus simple d'utiliser GCD pour ça : tu affiche un truc pour faire patienter l'utilisateur (UIActivityIndicator par exemple), tu demandes à  GCD d'exécuter ton algo long sur un thread (une "queue") secondaire, et une fois qu'il a fini, tu demandes à  GCD d'exécuter sur le main thread le code qui masque le UIActivityIndicator (puisque c'est du code qui manipule l'UI, contrairement à  ton algo long que tu as exécuté sur le thread secondaire)





    Mais dans ton cas, tu sembles dire que le code que tu exécutes dans "pushView:" fait un push d'un UIViewController, ce qui veut dire que c'est qqch qui manipule l'IHM / l'UI, donc c'est forcément à  faire dans le main thread, tu n'as pas le choix.





    PS : Pour archive, si ton opération longue n'était pas une opération qui affecte l'UI comme le push d'un ViewController, (mais un algo de calcul ou un download de données réseau ou tout autre truc n'intervenant pas sur l'IHM), avec GCD ça se ferait comme ça :
    // afficher à  l&#39;écran une vue qui demande à  l&#39;utilisateur de patienter. On est encore sur le main thread, donc pas de soucis<br />
    [self showWaitingView];<br />
    // exécuter ensuite le code de l&#39;algo long sur un thread (une &quot;queue&quot; GCD) secondaire et de façon asynchrone, donc en tâche de fond<br />
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{<br />
      // ici le code de la tâche un peu longue, genre ton algo complexe ou ton download ou quoi<br />
      ...blablabla<br />
      // et une fois fini, exécuter immédiatement après tout ce code en tâche de fond la mise à  jour de l&#39;UI (suppression de la vue qui faisait poireauter l&#39;utilisateur<br />
      dispatch_sync(dispatch_get_main_queue(), ^{<br />
        [self hideWaitingView];<br />
      });<br />
    });
    
  • D'accord,

    mais du coup je me demandais si c'étais possible d'annuler la tâche de fond?

    Imaginons que j'ai un viewController composé d'une tabBar, que je lance mon ActivityIndicator, pendant que mon code s'exécute en tâche de fond. Est il possible que pendant que mon ActivityIndicator tourne, je puisse annuler le code exécuter en tâche de fond on sélectionnant un de mes Items de ma tabBar et donc de terminer l'animation de mon ActivityIndicator ?
  • yass_1988yass_1988 Membre
    juin 2012 modifié #4
    En faite ce que je veux savoir, c'est que une fois l'activityIndicator lancé, je puisse encore interagir avec l'écran de mon téléphone, par exemple, j'ai un ViewController et une tabBar.
    [ViewController addSubview:activityIndicator]
    


    Si j'appuis sur un de mes item de la tabBAr, je peux arrêter l'activityIndicator avant qu'il ne s'arrête au moment prévus ?
  • AliGatorAliGator Membre, Modérateur
    Bah ça dépend de l'algo et de comment tu l'as écris.

    Tu peux surveiller régulièrement dans ton algo si un flag "operationCancelled" est passé à  YES ou pas, et si oui tout arrêter (en prenant soin de nettoyer derrière toi si tu avais des trucs en cours)
  • Bonjour,



    je relance le sujet, voila ou j'en suis, dans mon viewController, j'ai deux méthodes, -(void)sendRefreshDisplay et -(void)pushView:(NSIndexPath *)indexPath, la différence entre ces deux méthodes, c'est que pushView est appelé directement par mon viewController avec une méthode de détection d'un clique court sur un objet, pour me permettre de push vers une nouvelle vue,(riens de bien méchant), quand au deuxième, sendRefreshDisplay:, il est appelé après avoir sélectionné un bouton d'un UIActionSheet, actionSheet appelé dans le viewController, sauf que une fois le bouton appelé, je passe par une classe intermédiaire, qui va réaliser tout un long traitement et après appeler sendRefreshDisplay via un delegate implémenter par mon viewController.

    Le constat est que pour ma méthode -(void)pushView:(NSIndexPath *)indexPath tout se passe bien, mon code s'exécute pendant que mon indcatorActivity tourne et s'arrête à  la fin de mon code, parfait! Sauf que pour -(void)sendRefreshDisplay, mon code s'exécute, sans problème, mais mon indicatorActivity n'apparait pas et le plus étonnant c'est que à  la base de cette méthode, j'ai l'actionSheet, et une fois le bouton sélectionné, la vue d'actionSheet ne disparait seulement arrivé à  la ligne
    dispatch_async[color=#000000]([/color]dispatch_get_global_queue[color=#000000]([/color][color=#73492C]DISPATCH_QUEUE_PRIORITY_DEFAULT[/color][color=#000000],[/color][color=#3D01D9]0[/color][color=#000000]), ^{
    
    [/color]

    Donc voila en attendant, je suis dans l'impasse.


    - ([color=#b41ca4]void[/color]) sendRefreshDisplay<br />
    {<br />
    [color=#401082][color=#000000]	[[/color][color=#578187]indicator[/color][color=#000000] [/color]startAnimating[color=#000000]];[/color][/color]<br />
    [color=#401082][color=#000000]	[/color]dispatch_async[color=#000000]([/color]dispatch_get_global_queue[color=#000000]([/color][color=#73492c]DISPATCH_QUEUE_PRIORITY_DEFAULT[/color][color=#000000],[/color][color=#3d01d9]0[/color][color=#000000]), ^{[/color][/color]<br />
    [color=#578187][color=#000000]		[/color]ApplicationAlert[color=#000000] * AppAlert=[[[/color]ApplicationAlert[color=#000000] [/color][color=#401082]alloc[/color][color=#000000]] [/color][color=#38595d]init[/color][color=#000000]];[/color][/color]<br />
    		[color=#7134aa]NSArray[/color] * tabParamGetNoticesByApplication=[[color=#7134aa]NSArray[/color] [color=#401082]arrayWithObjects[/color]:[[color=#7134aa]NSNumber[/color] [color=#401082]numberWithInt[/color]:[color=#3d01d9]11[/color]], [[color=#578187]AuthTest[/color] [color=#38595d]token[/color]], [color=#b41ca4]nil[/color]];<br />
    		[color=#b41ca4]BOOL[/color] finish=[color=#b41ca4]NO[/color];<br />
    		[color=#b41ca4]while[/color](finish==[color=#b41ca4]NO[/color])<br />
    		{<br />
    			[color=#b41ca4]if[/color]([[AppAlert [color=#38595d]getNoticesByApplication[/color]:tabParamGetNoticesByApplication] [color=#401082]count[/color]]==[color=#3d01d9]0[/color])<br />
    			{<br />
    				finish=[color=#b41ca4]YES[/color];<br />
    			}[color=#b41ca4]else[/color] {<br />
    [color=#401082][color=#000000]				[/color][color=#7134aa]NSDate[/color][color=#000000] * to = [[[/color][color=#7134aa]NSDate[/color][color=#000000] [/color]alloc[color=#000000]] [/color]initWithTimeIntervalSinceNow[color=#000000]:[/color][color=#3d01d9]1.5[/color][color=#000000]];[/color][/color]<br />
    				[[color=#7134aa]NSThread[/color] [color=#401082]sleepUntilDate[/color]:to];<br />
    			}<br />
    		}<br />
    <br />
    [color=#38595d][color=#000000]		[/color][color=#578187]AppViewController[/color][color=#000000] * lGridViewController = [[[/color][color=#578187]AppViewController[/color][color=#000000] [/color][color=#401082]alloc[/color][color=#000000]] [/color]initWithGridLayoutStyle[color=#000000]:[/color]NRGridViewLayoutStyleVertical[color=#000000]];[/color][/color]<br />
    [color=#578187][color=#000000]		[[/color]FmContextViewController[color=#000000] [/color][color=#38595d]removeSelectedFile[/color][color=#000000]];[/color][/color]<br />
    		[lGridViewController [color=#38595d]setFmContext[/color]:[color=#578187]FmContextViewController[/color]];  <br />
    [color=#401082][color=#000000]		[[/color][color=#578187]tabBar[/color][color=#000000] [/color]removeFromSuperview[color=#000000]];[/color][/color]<br />
    		[lGridViewController [color=#38595d]setPath[/color]:[[color=#b41ca4]self[/color] [color=#38595d]path[/color]]];<br />
    		[lGridViewController [color=#38595d]initOrientationContext[/color]:[color=#b41ca4]self[/color]-&gt;[color=#578187]OrientationContext[/color]];<br />
    		[lGridViewController [color=#38595d]initTabPreviousCurrentPath[/color]];<br />
    [color=#38595d][color=#000000]		[lGridViewController [/color]setTabPreviousCurrentPath[color=#000000]:[[/color][color=#b41ca4]self[/color][color=#000000] [/color]tabPreviousCurrentPath[color=#000000]]];[/color][/color]<br />
    		[lGridViewController [color=#38595d]initArrayMethodeUser[/color]];<br />
    		[lGridViewController [color=#38595d]setArrayMethodeUser[/color]:[[color=#b41ca4]self[/color] [color=#38595d]arrayMethodeUser[/color]]];<br />
    [color=#38595d][color=#000000]		[lGridViewController [/color]initListeNamePathFileManagerSelected[color=#000000]];[/color][/color]<br />
    [color=#38595d][color=#000000]		[lGridViewController [/color]setListeNamePathFileManagerSelected[color=#000000]:[[/color][color=#b41ca4]self[/color][color=#000000] [/color]getListeNamePathFileManagerSelected[color=#000000]]];[/color][/color]<br />
    		[lGridViewController [color=#38595d]initCut[/color]:[[color=#b41ca4]self[/color] [color=#38595d]cutOrNotCut[/color]]];<br />
    [color=#73492c][color=#000000]		[/color][color=#401082]dispatch_sync[/color][color=#000000]([/color]dispatch_get_main_queue[color=#000000](), ^{[/color][/color]<br />
    			[[color=#578187]indicator[/color] [color=#401082]stopAnimating[/color]];<br />
    			[[color=#b41ca4]self[/color] [color=#38595d]pushWithContext[/color]:lGridViewController];<br />
    		});<br />
    	});<br />
    }<br />
    <br />
    <br />
    - ([color=#b41ca4]void[/color]) pushView:([color=#7134aa]NSIndexPath[/color] *)indexPath<br />
    {<br />
    	[color=#b41ca4]if[/color]([[[[[color=#578187]browseFeature[/color] [color=#38595d]getListFiles[/color]] [color=#401082]objectAtIndex[/color]:indexPath.[color=#7134aa]row[/color]] [color=#38595d]getType[/color]] [color=#401082]isEqualToString[/color]:[color=#c72c25]@&quot;directory&quot;[/color]])<br />
    	{<br />
    [color=#401082][color=#000000]		[[/color][color=#578187]indicator[/color][color=#000000] [/color]startAnimating[color=#000000]];[/color][/color]<br />
    <br />
    [color=#401082][color=#000000]		[/color]dispatch_async[color=#000000]([/color]dispatch_get_global_queue[color=#000000]([/color][color=#73492c]DISPATCH_QUEUE_PRIORITY_DEFAULT[/color][color=#000000],[/color][color=#3d01d9]0[/color][color=#000000]), ^{[/color][/color]<br />
    			[color=#7134aa]NSString[/color] * nextPath=[[[[color=#578187]browseFeature[/color] [color=#38595d]getListFiles[/color]] [color=#401082]objectAtIndex[/color]:indexPath.[color=#7134aa]row[/color]] [color=#38595d]getNom[/color]];<br />
    [color=#38595d][color=#000000]			[/color][color=#578187]AppViewController[/color][color=#000000] * gridViewController = [[[/color][color=#578187]AppViewController[/color][color=#000000] [/color][color=#401082]alloc[/color][color=#000000]] [/color]initWithGridLayoutStyle[color=#000000]:[/color]NRGridViewLayoutStyleVertical[color=#000000]];[/color][/color]<br />
    			[gridViewController [color=#38595d]setFmContext[/color]:[color=#578187]FmContextViewController[/color]];<br />
    		[color=#b41ca4]if[/color]([[[color=#b41ca4]self[/color] [color=#38595d]path[/color]] [color=#401082]isEqualToString[/color]:[color=#c72c25]@&quot;/&quot;[/color]])<br />
    		{<br />
    [color=#38595d][color=#000000]			[[/color][color=#b41ca4]self[/color][color=#000000] [/color]initTabPreviousCurrentPath[color=#000000]]; [/color][/color]<br />
    [color=#38595d][color=#000000]			[[/color][color=#b41ca4]self[/color][color=#000000] [/color]setObjectTabPreviousCurrentPath[color=#000000]:[[/color][color=#b41ca4]self[/color][color=#000000] [/color]path[color=#000000]]];[/color][/color]<br />
    			[color=#7134aa]NSString[/color] * addNextPath=[[color=#7134aa]NSString[/color] [color=#401082]stringWithFormat[/color]:[color=#c72c25]@&quot;/%@&quot;[/color],nextPath];<br />
    			[gridViewController [color=#38595d]setPath[/color]:addNextPath];<br />
    		}<br />
    		[color=#b41ca4]else[/color]<br />
    		{<br />
    [color=#38595d][color=#000000]			[[/color][color=#b41ca4]self[/color][color=#000000] [/color]setObjectTabPreviousCurrentPath[color=#000000]:[[/color][color=#b41ca4]self[/color][color=#000000] [/color]path[color=#000000]]];[/color][/color]<br />
    			[color=#7134aa]NSString[/color] * addNextPath=[[color=#7134aa]NSString[/color] [color=#401082]stringWithFormat[/color]:[color=#c72c25]@&quot;%@/%@&quot;[/color],[[color=#b41ca4]self[/color] [color=#38595d]path[/color]],nextPath];<br />
    			[gridViewController [color=#38595d]setPath[/color]:addNextPath];<br />
    		}<br />
    [color=#401082][color=#000000]		[[/color][color=#578187]tabBar[/color][color=#000000] [/color]removeFromSuperview[color=#000000]];[/color][/color]<br />
    		[gridViewController [color=#38595d]initOrientationContext[/color]:[color=#b41ca4]self[/color]-&gt;[color=#578187]OrientationContext[/color]];<br />
    		[gridViewController [color=#38595d]initTabPreviousCurrentPath[/color]];<br />
    [color=#38595d][color=#000000]		[gridViewController [/color]setTabPreviousCurrentPath[color=#000000]:[[/color][color=#b41ca4]self[/color][color=#000000] [/color]tabPreviousCurrentPath[color=#000000]]];[/color][/color]<br />
    		[gridViewController [color=#38595d]initArrayMethodeUser[/color]];<br />
    [color=#38595d][color=#000000]		[gridViewController [/color]setArrayMethodeUser[color=#000000]:[[/color][color=#b41ca4]self[/color][color=#000000] [/color]arrayMethodeUser[color=#000000]]];[/color][/color]<br />
    [color=#38595d][color=#000000]		[gridViewController [/color]initListeNamePathFileManagerSelected[color=#000000]];[/color][/color]<br />
    [color=#38595d][color=#000000]		[gridViewController [/color]setListeNamePathFileManagerSelected[color=#000000]:[[/color][color=#b41ca4]self[/color][color=#000000] [/color]getListeNamePathFileManagerSelected[color=#000000]]];[/color][/color]<br />
    		[gridViewController [color=#38595d]initCut[/color]:[[color=#b41ca4]self[/color] [color=#38595d]cutOrNotCut[/color]]];<br />
    <br />
    [color=#73492c][color=#000000]		[/color][color=#401082]dispatch_sync[/color][color=#000000]([/color]dispatch_get_main_queue[color=#000000](), ^{[/color][/color]<br />
    [color=#401082][color=#000000]		[[/color][color=#578187]indicator[/color][color=#000000] [/color]stopAnimating[color=#000000]];[/color][/color]<br />
    		[[color=#b41ca4]self[/color] [color=#38595d]pushWithContext[/color]:gridViewController];  <br />
    		});<br />
    		});<br />
    	}<br />
    }
    
Connectez-vous ou Inscrivez-vous pour répondre.