La question d'origine...............................................
Si vous êtes un utilisateur avancé de drawRect, vous savez que bien sûr drawRect ne sera pas réellement exécuter jusqu'à ce que "tout le traitement est terminé."
setNeedsDisplay drapeaux vue comme invalidé et les OS, et en gros, attend jusqu'à ce que tout le traitement est fait. Cela peut être exaspérant dans la situation où vous voulez avoir:
- un view controller 1
- commence une fonction 2
- qui a progressivement 3
- crée une plus compliquée et plus d'illustrations et de 4
- à chaque étape, vous setNeedsDisplay (faux!) 5
- jusqu'à ce que tout le travail est fait 6
Bien sûr, quand vous faites le au-dessus de 1-6, tout ce qui arrive est que drawRect est exécuté une seule fois après l'étape 6.
Votre but est de l'affichage pour être actualisé au point 5. Que faire?
La Solution de la question d'origine..............................................
En un mot, vous pouvez (A) de fond de la grande peinture, et d'appel à l'avant-plan de l'INTERFACE utilisateur des mises à jour ou (B), sans doute de façon controversée , il y a quatre "immédiat" des méthodes suggéré de ne pas utiliser un processus d'arrière-plan. Le résultat de ce qui fonctionne, exécutez le programme de démonstration. Il a #définit pour les cinq méthodes.
Époustouflant, une solution alternative introduite par Tom Swift..................
Tom Swift a expliqué l'incroyable idée de tout simplement la manipulation de l'exécution de la boucle. Voici comment déclencher l'exécution de la boucle:
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];
C'est vraiment un étonnant morceau de l'ingénierie. Bien sûr, on doit être extrêmement prudent lors de la manipulation de l'exécution de la boucle et comme beaucoup l'ont souligné, cette approche est strictement pour les experts.
Le Problème Bizarre Qui Se Pose..............................................
Même si un certain nombre de méthodes de travail, ils n'ont pas fait le "travail" parce qu'il est un étrange progressive du ralentissement de l'artefact, vous verrez clairement dans la démo.
Faites défiler jusqu'à la "réponse", j'ai collé ci-dessous, montrant la sortie de la console - vous pouvez voir comment il ralentit progressivement.
Voici le nouveau DONC, la question:
Mystérieux "ralentissement progressif" problème dans l'exécution de la boucle / drawRect
Voici la V2 de la démo app...
http://www.fileswap.com/dl/p8lU3gAi/stepwiseDrawingV2.zip.html
Vous verrez qu'il teste tous les cinq méthodes,
#ifdef TOMSWIFTMETHOD
[self setNeedsDisplay];
[[NSRunLoop currentRunLoop]
runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]];
#endif
#ifdef HOTPAW
[self setNeedsDisplay];
[CATransaction flush];
#endif
#ifdef LLOYDMETHOD
[CATransaction begin];
[self setNeedsDisplay];
[CATransaction commit];
#endif
#ifdef DDLONG
[self setNeedsDisplay];
[[self layer] displayIfNeeded];
#endif
#ifdef BACKGROUNDMETHOD
// here, the painting is being done in the bg, we have been
// called here in the foreground to inval
[self setNeedsDisplay];
#endif
Vous pouvez voir par vous-même les méthodes qui fonctionnent et celles qui ne le sont pas.
vous pouvez voir l'étrange "progressif-slow down". pourquoi se produit-il?
vous pouvez voir avec le controversé TOMSWIFT méthode, il n'y a effectivement pas de problème de réactivité. appuyez sur pour la réponse en tout temps. (mais encore l'étrange "progressif-slow-down" (problème)
Si l'écrasante, c'est bizarre "progressif-slow-down": à chaque itération, pour des raisons inconnues, le temps pris pour une boucle de décès. Notez que cela s'applique à la fois à le faire "correctement" (fond d'oeil) ou à l'aide de l'un des "immédiat" des méthodes.
Des solutions pratiques ........................
Pour tous ceux qui lisent dans l'avenir, si vous êtes réellement incapable d'obtenir que cela fonctionne dans le code de production en raison de la "mystère ralentissement progressif" ... Felz et Vide, ont chacun présenté d'étonnantes solutions dans d'autres question spécifique, j'espère que ça aide.