37 votes

Avertissement CoreAnimation supprimé thread avec CATransaction non engagé

Je vais avoir des problèmes avec l'avertissement suivant:

CoreAnimation: avertissement, supprimé avec du fil non validées CATransaction; ensemble CA_DEBUG_TRANSACTIONS=1 dans l'environnement journal backtraces.

Je suis en utilisant un NSOperation objet pour effectuer certains calculs, une fois terminé, il envoie un message à l'AppDelegate qui dissimule une barre de progression et permet de faire apparaître des boutons. Si je commente le message de retour à l'AppDelegate l'avertissement disparaît mais la barre de progression, évidemment, reste visible et d'animation.

J'utilise xCode 4.4.1 et OS x 10.8.1, cependant, quand j'ai compiler et exécuter le code en utilisant la même version de xCode sur mac OSX 10.7.4 je n'ai pas l'avertissement et le code s'exécute comme prévu.

Réglage de la CA_DEBUG_TRANSACTIONS=1 la variable d'environnement montre la trace comme venant d'un NSControl setEnabled message dans le AppDelegate.

La réponse est probablement regarder moi dans le visage, mais peut-être que j'ai eu trop de café!

24voto

numist Points 209

Conformément aux normes de Cacao paradigmes, la solution recommandée est de faire de Base de votre travail d'Animation sur le thread principal, facile à faire avec PGCD:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.delegate redrawSomething];
});

En général c'est une mauvaise forme d'appeler des objets dans des contextes qu'ils ne prévoient pas, donc c'est une bonne règle de base est de toujours expédition sur le thread principal lors de la remise des messages à des modules externes.

Certains cadres de Base en forme de Localisation à émettre un message de log si elles sont appelées à partir d'un autre contexte que le thread principal. D'autres vont émettre des messages cryptiques, comme votre exemple ici avec Core Animation.

19voto

Jean Points 7685

Vos soupçons sont à droite. Si NSOperation se termine avant CoreAnimation est fait effectuer, alors vous obtenez un joli avertissement:

*CoreAnimation: avertissement, supprimé avec du fil non validées CATransaction; ensemble CA_DEBUG_TRANSACTIONS=1 dans l'environnement journal backtraces.*

Cela peut également se produire dans certaines circonstances lorsqu'un bloc qui est distribué sur une file d'attente déclenche des travaux de CoreAnimation et renvoie devant la CoreAnimation finitions.

La solution que j'utilise est simple: Sur un bloc ou NSOperation que les demandes de travail à partir de CoreAnimation, j'ai vérifier que le travail a en effet été réalisée avant la sortie.

Pour vous donner une preuve de concept exemple, c'est un bloc à être distribué sur un message de la file d'attente. Afin d'éviter l'avertissement, nous vérifions que le CoreAnimation est fait avant de quitter.

^{

   // 1. Creating a completion indicator

   BOOL __block animationHasCompleted = NO;

   // 2. Requesting core animation do do some work. Using animator for instance.

   [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context){
      [[object animator] perform-a-nice-animation];
   } completionHandler:^{
      animationHasCompleted = YES;
   }];

   // 3. Doing other stuff…

   …

   // 4. Waiting for core animation to complete before exiting

   while (animationHasCompleted == NO)
   {
       usleep(10000);
   }

}

8voto

Dalmazio Brisinda Points 887

Une autre façon de s'assurer que tout dessin d'INTERFACE utilisateur se produit sur le thread principal, tel que décrit par Numist, est à l'aide de la méthode de performSelectorOnMainThread:withObject:waitUntilDone: ou alternativement performSelectorOnMainThread:withObject:waitUntilDone:modes:

- (void) someMethod
{
    [...]

    // Perform all drawing/UI updates on the main thread.
    [self performSelectorOnMainThread:@selector(myCustomDrawing:)
                           withObject:myCustomData
                        waitUntilDone:YES];

    [...]
}

- (void) myCustomDrawing:(id)myCustomData
{
    // Perform any drawing/UI updates here.
}


Pour un poste sur la différence entre dispatch_async() et performSelectorOnMainThread:withObjects:waitUntilDone: voir quel est la différence entre performSelectorOnMainThread et dispatch_async sur la file d'attente principale?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X