2010-11-20 4 views
5

Le suivi des événements dans UIScrollview bloque le thread principal. J'utilise le thread principal pour exécuter une minuterie qui entraîne une animation - le résultat est que toute interaction de l'utilisateur avec la vue défilante (en la faisant glisser vers le haut ou vers le bas, etc.) gèle l'animation (exécutée sur le runloop principal). Y a-t-il un moyen de contourner ceci? J'ai essayé RTFM à propos de NSRunloop (CFRunLoopAddCommonMode et al), mais c'est assez laconique, ce qui me laisse croire que le bricolage avec les priorités d'événements/priorités de thread est mieux évité. Quelqu'un a-t-il un aperçu?Le suivi des événements dans UIScrollView bloque le thread principal. Des correctifs?

+1

Vous ne pouvez effectuer que des tâches d'interface utilisateur dans le thread principal, de sorte que le fait de jouer avec les priorités de thread ne s'applique pas. Je suis curieux - savez-vous si les NSTimers arrêtent de tirer, ou si les minuteurs se déclenchent, mais refusent d'appliquer les changements que vous faites dans l'animation? L'animation est-elle faite * vers * UIScrollView, ou * dans * scrollview? C'est-à-dire que vous essayez d'animer et de changer la même chose que le scrollview essaye de changer? (Faire défiler la vue rects, etc)? – Brad

+0

Merci, Brad - ce que j'espérais (probablement dangereusement) faire était d'ajouter le mode EventTracking au runloop principal, lui permettant ainsi de continuer à fonctionner en même temps que le runloop EventTracking. L'animation qui est bloquée est en fait effectuée sur une vue entièrement différente de celle qui contient le scrollview. Pour répondre à votre autre question, le NSTimer arrête complètement de tirer. Il semble complètement bloqué par l'activité de priorité supérieure de suivi des événements de l'utilisateur sur le UIScrollView (non apparenté). –

Répondre

16

Au lieu d'utiliser l'un des constructeurs statiques de NSTimer, créer l'objet de la minuterie et le programmer comme manuellement ceci:

NSTimer *timer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:delayInSeconds] interval:0 target:yourObject selector:yourSelector userInfo:nil repeats:NO]; 
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 
[timer release]; 

Votre paramters à initWithFireDate: sera tout à fait différent bien sûr, d'autant qu'il semble que vous » re en utilisant une minuterie répétitive. Je pense que vous pouvez voir l'idée de base cependant. Lorsque vous faites défiler la boucle d'exécution passe dans un mode qui empêche les tâches de "mode par défaut" d'exécuter. Les fonctions statiques NSTimer sont toutes programmées dans le mode par défaut, c'est pourquoi elles ne se déclenchent pas pendant le défilement. La planification manuelle de la minuterie vous permet de spécifier le mode et NSRunLoopCommonModes inclut le mode d'exécution utilisé par défilement.

+0

Brillant! J'avais utilisé: \t [[NSRunLoop mainRunLoop] addTimer: loopTimer forMode: [NSRunLoop currentMode]]; qui était toujours bloqué. Votre réparation fonctionne parfaitement. –

+0

Merci un billion! Cette correction augmente considérablement la facilité d'utilisation de ma table de chargement paresseuse. – Nailer

0

Une idée consiste à faire fonctionner la minuterie sur un fil séparé. Lorsque la minuterie se déclenche, alors faites ce qu'il faut pour l'exécuter sur le thread principal.

Edit:

Ah oui, je complètement oublié comment les blocs UIScrollView à peu près tout. Une autre idée (quoique très laide) est de vérifier si le temporisateur a tiré pendant les méthodes de délégué (c'est-à-dire -scrollviewDidScroll, etc.) de l'UIScrollView. C'est en quelque sorte un hack, mais c'est essentiellement la seule façon dont je suis conscient de pouvoir exécuter n'importe quel code pendant le défilement.

+0

Merci, oui, je suis déjà en cours d'exécution mon minuteur d'animation sur le fil principal. Il semble que le suivi en coulisse des événements utilisateur soit prioritaire par rapport au thread principal, donc quand quelque chose de continu (comme le défilement) arrive, il bloque le fil principal pendant longtemps ... –

+0

@Andy Milburn: Voir modifier pour une autre idée. –

Questions connexes