2009-07-29 13 views
6

Tengo un problema de retención/liberación. Mi vista es bastante complicada, así que configuré NSZombieEnabled en SÍ y trato de localizar cuál es exactamente el objeto que me está causando dolor. Para acelerar este proceso, me pregunto si hay pistas o trucos para rastrear a los Zombies hasta la tumba de la que salieron (lo siento, tuvieron que hacerlo) o, de vuelta al objeto al que están asociados. El mensaje de la consola críptica no parece ofrecer una visión mucho más:¡NSZombies están comiendo el cerebro de mi aplicación!

NSInvocation: warning: object 0x1076850 of class '_NSZombie_CALayer' does not implement methodSignatureForSelector: -- trouble ahead 

no tengo selectores llamados "problemas en el futuro".

Editar - La inclusión de Seguimiento de la pila:

#0 0x3026e017 in ___forwarding___ 
#1 0x3024a0a2 in __forwarding_prep_0___ 
#2 0x302042e8 in CFRelease 
#3 0x00c4fc31 in CALayerUpdateSublayers 
#4 0x00c4e173 in -[CALayer dealloc] 
#5 0x00c4000e in CALayerRelease 
#6 0x00c48dad in CALayerFreeTransaction 
#7 0x00c410b8 in CA::Transaction::commit 
#8 0x00c492e0 in CA::Transaction::observer_callback 
#9 0x30245c32 in __CFRunLoopDoObservers 
#10 0x3024503f in CFRunLoopRunSpecific 
#11 0x30244628 in CFRunLoopRunInMode 
#12 0x32044c31 in GSEventRunModal 
#13 0x32044cf6 in GSEventRun 
#14 0x309021ee in UIApplicationMain 
#15 0x00001eb4 in main at main.m:14 

Edición 2: ObjectAlloc

Mirando hacia arriba la dirección de memoria en cuestión en ObjectAlloc Encuentro dos partidos:

# Address  Category   Creation Time  Size Responsible Library Responsible Caller 
0 0x1076980 GeneralBlock-48 00:11.470  48  QuartzCore -[CALayer setDelegate:] 
1 0x1076980 CALayer   00:11.552  48  UIKit  -[UIView _createLayerWithFrame:] 

la excavación en # 0 GeneralBlock-48:

# Category  Event Type Timestamp Address Size Responsible Library Responsible Caller 
0 GeneralBlock-48 Malloc  00:11.470 0x1076980 48 QuartzCore -[CALayer setDelegate:] 
1 GeneralBlock-48 Free  00:11.551 0x1076980 -48 QuartzCore -[CALayer addAnimation:forKey:] 
2 CALayer   Malloc  00:11.552 0x1076980 48 UIKit -[UIView _createLayerWithFrame:] 

Excavando en # 1 CALayer:

# Category  Event Type Timestamp Address Size Responsible Library Responsible Caller 
0 GeneralBlock-48 Malloc  00:11.470 0x1076980 48 QuartzCore -[CALayer setDelegate:] 
1 GeneralBlock-48 Free  00:11.551 0x1076980 -48 QuartzCore -[CALayer addAnimation:forKey:] 
2 CALayer   Malloc  00:11.552 0x1076980 48 UIKit -[UIView _createLayerWithFrame:] 

Bueno, ahora veo que la perforación más profunda, ya sea en # 0 o # 1 pone de manifiesto la misma información. Supongo que debería reducir la resolución de problemas a la mitad ... pero todavía estoy en una pérdida ...

+1

¿Has probado la programación de escopetas en tu aplicación? – Sneakyness

+1

Tomé un atajo y probé la estaca de madera ... ay, eso solo funciona en NSVampires :-( – Meltemi

+0

+1 para los detalles de la pregunta, y el interesante título: D –

Respuesta

6

Creo que la traza inversa es solo el punto donde se está enviando un mensaje al zombi. Esta traza inversa por lo general le brinda cero información sobre lo que está causando el colapso. Más o menos, solo te dice el tipo y la dirección del objeto que se está liberando en exceso.

Una técnica que a menudo uso para rastrear los sobre-lanzamientos como este es usar ObjectAlloc de Instruments para rastrear todos los retenciones y lanzamientos. Busque la dirección del objeto liberado en exceso en ObjectAlloc, luego enumere todas las llamadas de retención/liberación y luego intente equilibrar cada retención con un lanzamiento. Una vez que encuentre un lanzamiento sin un retener para que coincida, ha encontrado el problema.

+0

Lo sentimos, pero ¿cómo "enumera todas las llamadas de retener/liberar" en Instruments? – Meltemi

+1

En la vista de tabla que muestra todas las asignaciones, haga clic en la flecha junto a "* Todas las asignaciones *". Busque la dirección del zombie CALayer (puede pegarla en el campo de búsqueda a continuación). Haga clic en la flecha al lado de esa dirección. Verás una lista de todas las llamadas malloc/free/retain/release en esa dirección. Abra la barra lateral para ver el seguimiento de la pila para cada llamada. – kperryua

+0

¡Gracias! ¡Servicial! Pero cuando corro con ObjectAlloc los NSZombies no aparecen. Entonces no puedo comparar esa dirección con lo que está en la lista. Creo que Instruments elude el Debugger y la consola de XCode. Ah, creo que acabo de responder esa parte de la pregunta: Mire en Console.app y no en la consola de XCode ... – Meltemi

2

Una cosa rápida que puede hacer es establecer un punto de interrupción simbólica en objc_exception_throw. Esto hará que su programa se detenga cada vez que se lanza una excepción. Es posible que esto no ayude a rastrear exactamente, que CALayer le está causando dolor, pero debería ayudarlo a encontrar la vecindad general donde se llama.

+0

de acuerdo, necesita saber exactamente cuándo está sucediendo esto. –

+0

Tenía habilitado el punto de interrupción objc_exception_throw pero para mí es tan críptico. Lo publiqué arriba. – Meltemi

+0

¿Cuál es el contexto de este error? ¿Qué haces con tu programa para hacerlo disparar? Desde el seguimiento de la pila, parece que está sucediendo al final de una transacción de CA, lo que significa que es una apuesta segura que esto llegue al final de una animación. ¿Hay una animación disparando? Si es así, ¿qué capas están involucradas? ¿Estás asegurándote de "retener" los que intentas usar de nuevo? – Alex

2

"trouble ahead" es parte de la advertencia, no del selector. La advertencia en sí viene de NSInvocation, pero el hecho de que menciona "class _NSZombie_CALayer" significa que algo está tratando de trabajar con un CALayer que ha sido desasignado.

El seguimiento de la pila indica que esto está sucediendo cuando una capa intenta liberar sus subcapas.

En total, esto significa que la capa que se está liberando tiene una subcapa que ha sido liberada en exceso en algún lugar de su código. Verifique su administración de memoria de CALayers o pruebe el Clang Static Analyzer.

Cuestiones relacionadas