2010-05-06 4 views
0

J'ai une application qui effectue des calculs basés sur des données arrivant sur une socket ou une interaction utilisateur locale.les mises à jour de la vue en file d'attente ne se produisent pas lorsque performSelector afterDelay: 0 used

Je souhaite afficher un 'spinner d'activité' pendant le calcul.

spinner = [[UIActivityIndiactorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
[spinner setCenter:self.view.center]; 
[self.view addSubview:spinner]; 
[spinner startAnimating]; 
[self performSelector:@selector(doCalcs) withObject:nil afterDelay:0]; 

Cela fonctionne bien, sauf dans le cas où le code est exécuté à la suite de l'arrivée d'un message sur le réseau. J'utilise http://code.google.com/p/cocoaasyncsocket/ pour gérer les sockets et le code s'exécute dans la méthode onSocket: didReadData: withTag:.

'doCalcs' prend quelques secondes. Le spinner n'apparaît pas pendant qu'il est en cours d'exécution.

Si je change afterDelay: 0 à afterDelay: 1 alors le spinner apparaît tout le temps que doCalcs est en cours d'exécution, mais avec le downside cela prend une seconde supplémentaire. Donc, il semble que le code soit correct, mais pour une raison quelconque, le spinner n'a pas l'occasion de passer à l'écran avant que doCalcs ne fonctionne.

Toutes les suggestions seraient les bienvenues.

+0

afterDelay: 0.1 fonctionne également, ce qui est peut-être un compromis raisonnable. – JosephH

Répondre

1

Vous pouvez essayer de faire vos calculs sur un fil d'arrière-plan pour empêcher l'animation de bloquer:

[self performSelectorInBackground:@selector(doCalcs)withObject:nil]; 
+0

Merci, cela semble être une alternative raisonnable. Je pense toujours qu'il y a quelque chose qui n'est pas clair sur l'ordre dans lequel s'effectuent les mises à jour de showSelector() et de view, mais je suppose que c'est non documenté/non garanti. – JosephH

0

Au lieu d'un sélecteur, vous devez générer un thread pour effectuer vos calculs. L'interface utilisateur est mise à jour uniquement si l'application autorise les déplacements dans la boucle d'événements. et votre méthode bloque. Alternativement, vous pouvez avoir une minuterie appeler votre méthode "doCalcs" périodiquement jusqu'à ce qu'ils soient complets ... elle devrait sortir après une période de temps définie afin que la boucle d'événement puisse s'exécuter et faire les calculs dans "tranches". Si vous avez besoin de plus de direction faites le moi savoir!

Questions connexes