2009-04-06 8 views
2

J'ai quelques onglets dans mon application iPhone qui prennent quelques secondes à charger (en tirant de grandes quantités de données à partir d'une base de données sqlite locale). Lorsque les utilisateurs touchent les onglets, il apparaît que l'application ne fait absolument rien. J'ai essayé de mettre une fenêtre montrant un fileur, mais il n'est jamais montré en raison du fait que le traitement suit immédiatement.NSRunloops et forcer le traitement des événements

Je sais que j'ai quelques options différentes pour charger les données de manière asynchrone, mais je voulais interroger la communauté et voir s'il y avait des problèmes potentiels avec juste forcer un autre cycle de NSRunloop pour montrer la fenêtre.

Voici ce que mon code ressemble ...

[[ActivityIndicator sharedActivityIndicator] show]; 
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]]; 

Sur une échelle de 1 à 10 à quel point évaluez-vous ce hack?

Répondre

3

Je ne sais pas où je l'évaluerais, mais je sais que je ne voudrais pas le faire de cette façon. Messing avec le runloop par défaut du système semble juste une mauvaise idée.

Il y a un certain nombre de ce que je pense être de bonnes approches. Le plus simple est de mettre le traitement supplémentaire dans une méthode privée séparée, puis faire:

[[ActivityIndicator sharedActivityIndicator] show]; 
[self performSelector:@selector(processingMethod) withObject:nil afterDelay:0]; 

Cela provoquera processingMethod d'être appelé à la fin de la boucle d'exécution, après votre indicateur montre. Devrait fonctionner correctement. Le seul inconvénient est que si votre indicateur est animé, en fonction de la façon dont il est configuré, il peut ne pas être animé pendant le processingMethod est en cours d'exécution. Dans ce cas, vous auriez à exécuter processingMethod dans un thread d'arrière-plan, ce qui pourrait être un peu plus compliqué, ou peut-être aussi simple que de faire ceci:

[self performSelectorInBackground:@selector(processingMethod) withObject:nil]; 

La complication potentielle, il est à la fin de processingMethod, lorsque vous allez afficher les résultats de votre traitement, vous devrez peut-être rappeler une méthode sur le thread principal.

+0

Je suis d'accord avec Jack et je pense que Lounges cherche sa deuxième réponse « performSelectorInBackground » - avec rappel. – mobibob

1

Mon expérience est que le code de gestion d'événements sur iPhone n'est pas réentrant. Donc, si vous exécutez le runloop en mode par défaut, soyez prêt pour divers accidents. que j'ai trouvé d'autres ont de problème aussi:

  1. http://lists.apple.com/archives/xcode-users/2009/Apr/msg00313.html
  2. http://www.iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/16246-trying-make-modal-dialog-using-nested-nsrunloop.html
+0

Vous avez raison, et de plus, le document d'Apple indique que le thread n'est pas réentrant. Vous ne devez pas accéder aux données d'autres threads. Le rappel - et «donner les données» - est l'approche préférée. – mobibob

+0

Que voulez-vous dire par réentrant? – airpaulg

Questions connexes