2011-11-28 16 views
42

Presioné ALT + CMD + R y activé NSZombieEnabled en Argumentos> Variables de entorno. Además, lo activé en Diagnósticos> Administración de memoria> Activar objetos zombi.¿Cómo depurar el "mensaje enviado a la instancia desasignada" en Xcode4?

Sin embargo, cuando construí y correr, en algún momento mis aplicación se bloquea darme este mensaje inútil en la consola:

*** -[CALayer retainCount]: message sent to deallocated instance 0x656b260 

El seguimiento de pila es igual de inútil. Moví el control deslizante de nivel de detalles hacia la derecha. 1 hilo simplemente me muestra esto:

screenshot

Todo es propiedad del sistema y no hay una sola línea en relación con mi aplicación. Así que obviamente NSZombiesEnabled no funciona como lo hizo en Xcode 3, donde se detuvo en el objeto muerto.

¿Hay alguna manera de averiguar que CALayer se desasigna demasiado pronto?

Actualización: Entonces, después de construir y ejecutar aproximadamente 100 veces más, de repente el problema desapareció. ¡Se ha ido por completo! Y la mejor parte: ¡no modifiqué mi código de ninguna manera! Entremedio, limpié la carpeta de compilación y proyecto con los comandos limpios varias veces y también borré la aplicación en el simulador varias veces.

Actualización 2: Afortunadamente el problema volvió a aparecer. Y ahora parece persistente. Afortunadamente, porque prefiero encontrar la causa raíz en lugar de molestar a los usuarios de forma aleatoria.

Actualización 3: Finalmente encontramos por casualidad:

startButton = newBttn; 

debería haber sido:

self.startButton = newBttn; 

startButton era una propiedad de retención y en -dealloc me soltó. Así que se soltó mucho y en la mayoría (pero no en todos) los casos después de que la vista se desvaneciera, se bloqueó al dar ese extraño mensaje de retención de CALayer.

El Zombies Instrument (CMD + I) finalmente señaló que tenía que ver con un botón. Simplemente no sabía por qué y dónde.

Clang Static Analyzer no se quejó de este error obvio.

+0

No sólo fallo "soluciones en sí". Es muy probable que se trate de un problema de propiedad relacionado con la concurrencia y es bastante probable que aún exista en el código. Una bomba de relojería, si quieres. En sus zapatos, analizaré muy detenidamente cómo estoy administrando los recursos basados ​​en Core Animation ... – bbum

+0

¿Qué quiere decir exactamente con recursos basados ​​en Core Animation? – dontWatchMyProfile

+0

Cualquier cosa relacionada con tirar basura en la pantalla. Si está demandando a cocos2d, deberá revisar su administración de los recursos que contiene, ya que administra indirectamente los recursos de CA *. – bbum

Respuesta

88

Si esto vuelve a surgir, puede ejecutar un instrumento dedicado de Zombies. Pulse Comando + I para crear un perfil de la aplicación y seleccionar el instrumento Zombies (debe estar ejecutándose en el simulador). Si obtienes un zombie, puedes mostrar todo el historial de memoria (cada retener/liberar) para ese objeto, lo cual es inmensamente útil para rastrear errores.

+0

¡Gran herramienta! ¡Gracias! A pesar de que muestra un mejor seguimiento de pila ahora, no puedo entender qué UIView posee ese zombie CALayer. ¿Puedes señalar un buen recurso que muestra cómo usar ese instrumento en un caso como este? – dontWatchMyProfile

+0

Excelente, gran respuesta, gracias – Sam

+0

Esto acaba de hacer mi día. No tenía idea de que pudieras perfilar una aplicación como esa. No tienes idea de lo feliz que estoy ahora. – shulmey

46

Además de la excelente respuesta de Jeff; para hacer casi lo mismo, pero sin tener que abrir Instruments o crear un perfil de su aplicación, puede configurar NSZombieEnabled, MallocStackLogging y guard malloc en el depurador. Entonces, cuando su aplicación se cierra, escriba esto en la consola GDB:

(gdb) info malloc-history 0x543216 

Reemplazar 0x543216 con la dirección del objeto que causó el accidente, y obtendrá un mucho más útil seguimiento de la pila y debe ayudar a identificar la línea exacta en su código que está causando el problema.

This article has some additional infoz.

+0

Creo que la herramienta Zombies es básicamente un envoltorio de interfaz gráfica de usuario en torno a este procedimiento exacto, simplemente se encarga de algunos de los trabajos más difíciles para usted. – Olie

+12

Desafortunadamente esto no funciona con LLDB – Chris

+20

FYI: Con el depurador LLDB puede hacerlo de la siguiente manera: (LLDB) script de importación lldb.macosx.heap (LLDB) malloc_info --stack-historia 0x7c506a00 – Ron

Cuestiones relacionadas