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?
Répondre
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.
Brillant! J'avais utilisé: \t [[NSRunLoop mainRunLoop] addTimer: loopTimer forMode: [NSRunLoop currentMode]]; qui était toujours bloqué. Votre réparation fonctionne parfaitement. –
Merci un billion! Cette correction augmente considérablement la facilité d'utilisation de ma table de chargement paresseuse. – Nailer
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.
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 ... –
@Andy Milburn: Voir modifier pour une autre idée. –
- 1. Thread.join bloque le thread principal
- 2. Le But principal des événements en C#
- 3. Dispatcher.Invoke se bloque lorsque le thread principal appelé Thread.Join
- 4. Suivi des événements
- 5. Passer des événements à UIScrollView
- 6. Suivi des événements d'un contrôle
- 7. Comment faire pour que CATiledLayer ne bloque pas le thread principal
- 8. Lever des exceptions non gérées dans un thread dans le thread principal?
- 9. Le nouveau thread bloque toujours l'UI-Thread
- 10. Exception dans le thread "principal" java.lang.NoSuchMethodError: principale
- 11. Exception dans le thread "principal" java.lang.NoClassDefFoundError
- 12. [Threading CLR] Lorsqu'un thread de thread thread bloque, le pool de threads crée des threads supplémentaires
- 13. Comment tuer le thread principal du sous-thread dans Jython
- 14. Accéder au thread principal avec le rappel
- 15. Suivi des événements asynchrones Google Analytics
- 16. Log4Net fonctionne dans le thread principal mais pas dans le thread créé
- 17. Évitez que le thread principal ne se bloque lorsque UIWebView tente de verrouiller de manière bloquante le thread Web
- 18. Exécuter du code dans le contexte du thread principal (Lazarus)
- 19. Événements de redimensionnement de la fenêtre SFML bloquant le thread principal
- 20. Stockage des événements utilisateur dans le backend
- 21. NSOperation et NSNotificationCenter sur le thread principal
- 22. Comment intercepter l'exception dans le thread principal si l'exception se produit dans le thread secondaire?
- 23. Contrôler le travail des threads de travail via le thread principal
- 24. Asp.net Evénement pour le suivi des modifications des entités
- 25. comment résoudre cette exception: Exception dans le thread « principal » java.lang.ArrayIndexOutOfBoundsException
- 26. NSInvocationOperation et thread principal
- 27. erreur java: Exception dans le thread "principal" java.lang.NullPointerException
- 28. L'appel Win32 CreateWindow() se bloque dans le thread enfant?
- 29. Exception dans le thread "principal" java.lang.IllegalArgumentException: n doit être positif
- 30. Variables globales non détruites dans le thread principal?
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
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é). –