threads threading thread get_ident example current_thread commands multithreading core-animation nsoperation catransaction

multithreading - threading - La advertencia de CoreAnimation borró el hilo con CATransaction no confirmada



threading.timer python (3)

De acuerdo con los paradigmas estándar de Cocoa, la solución recomendada aquí es realizar su trabajo de Core Animation en el hilo principal, fácil de hacer con GCD:

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

En general, no es correcto llamar a los objetos en contextos que no esperan, por lo que una buena regla general es enviarlos siempre al hilo principal al enviar mensajes a módulos externos.

Algunos marcos, como Core Location, emiten un mensaje de registro si se invocan desde cualquier contexto que no sea el hilo principal. Otros emitirán mensajes crípticos, como su ejemplo aquí con Core Animation.

Tengo problemas con la siguiente advertencia:

CoreAnimation: advertencia, hilo eliminado con CATransaction no confirmada; establezca CA_DEBUG_TRANSACTIONS = 1 en el entorno para registrar backtraces.

Estoy usando un objeto NSOperation para realizar algunos cálculos, una vez completado, envía un mensaje de regreso a AppDelegate que luego oculta una barra de progreso y muestra algunos botones. Si vuelvo a comentar el mensaje de regreso a AppDelegate, la advertencia desaparece, pero la barra de progreso obviamente permanece visible y animada.

Estoy usando xCode 4.4.1 y OSX 10.8.1, sin embargo, cuando compilo y ejecuto el código usando la misma versión de xCode en OSX 10.7.4 no recibo la advertencia y el código se ejecuta como se esperaba.

La configuración de la variable de entorno CA_DEBUG_TRANSACTIONS = 1 muestra que la traza inversa proviene de un mensaje NSControl setEnabled en AppDelegate.

La respuesta probablemente me está mirando a la cara, ¡pero tal vez he tomado demasiado café!


Otra forma de garantizar que cualquier dibujo de UI ocurra en el hilo principal, como lo describe Numist, es usar el método performSelectorOnMainThread:withObject:waitUntilDone: o alternativamente 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. }


Para una publicación relacionada sobre la diferencia entre dispatch_async() y performSelectorOnMainThread:withObjects:waitUntilDone: vea ¿ Cuál es la diferencia entre performSelectorOnMainThread y dispatch_async en la cola principal?


Tus sospechas son correctas. Si NSOperation finaliza antes de que CoreAnimation finalice la ejecución, entonces obtienes una buena advertencia:

* CoreAnimation: advertencia, hilo eliminado con CATransaction no confirmada; establezca CA_DEBUG_TRANSACTIONS = 1 en el entorno para registrar backtraces. *

Esto también puede ocurrir en algunas circunstancias cuando un bloque que se distribuye en una cola desencadena algún trabajo de CoreAnimation y regresa antes de que termine CoreAnimation.

La solución que uso es simple: en un bloque o NSOperation que solicita trabajo desde CoreAnimation, compruebo que el trabajo se haya completado antes de salir.

Para darle un ejemplo de prueba de concepto, este es un bloque que se enviará en una cola de despacho. Para evitar la advertencia, verificamos que CoreAnimation esté listo antes de salir.

^{ // 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); } }