Señal EXC_BAD_ACCESS recibida
Al implementar la aplicación en el dispositivo, el programa se cerrará después de algunos ciclos con el siguiente error:
Program received signal: "EXC_BAD_ACCESS".
El programa se ejecuta sin ningún problema en el simulador de iPhone, también se depurará y se ejecutará siempre que siga las instrucciones una a la vez. Tan pronto como lo deje funcionar nuevamente, daré la EXC_BAD_ACCESS
señal.
En este caso particular, resultó ser un error en el código del acelerómetro. No se ejecutaría dentro del simulador, por lo que no arrojó ningún error. Sin embargo, se ejecutará una vez implementado en el dispositivo.
La mayoría de las respuestas a esta pregunta tratan sobre el EXC_BAD_ACCESS
error general, por lo que dejaré esto abierto como un todo para el temido error de acceso incorrecto.
EXC_BAD_ACCESS
Por lo general, se genera como resultado de un acceso ilegal a la memoria. Puede encontrar más información en las respuestas a continuación.
¿Ha encontrado la EXC_BAD_ACCESS
señal antes y cómo la resolvió?
Por tu descripción sospecho que la explicación más probable es que tienes algún error en la gestión de la memoria. Dijiste que has estado trabajando en el desarrollo de iPhone durante algunas semanas, pero no sabes si tienes experiencia con Objective C en general. Si proviene de otros orígenes, puede tomar un poco de tiempo antes de que realmente internalice las reglas de administración de memoria, a menos que le dé mucha importancia.
Recuerde, cualquier cosa que obtenga de una función de asignación (generalmente el método de asignación estática, pero hay algunos otros), o un método de copia, también es dueño de la memoria y debe liberarla cuando haya terminado.
Pero si obtiene algo a cambio de cualquier otra cosa, incluidos los métodos de fábrica (por ejemplo [NSString stringWithFormat]
), tendrá una referencia de liberación automática, lo que significa que podría ser liberado en algún momento en el futuro mediante otro código, por lo que es vital que si necesita para mantenerlo más allá de la función inmediata para la que lo conserva. Si no lo hace, es posible que la memoria permanezca asignada mientras la usa, o que se libere, pero coincidentemente sigue siendo válida, durante la prueba del emulador, pero es más probable que se libere y se muestre como errores de acceso incorrectos cuando se ejecuta en el dispositivo.
La mejor manera de rastrear estas cosas, y una buena idea de todos modos (incluso si no hay problemas aparentes) es ejecutar la aplicación en la herramienta Instrumentos, especialmente con la opción Fugas.
Una de las principales causas de EXC_BAD_ACCESS es intentar acceder a objetos liberados.
Para saber cómo solucionar este problema, lea este documento: DebuggingAutoReleasePool
Incluso si no cree que esté "liberando objetos liberados automáticamente", esto se aplicará a usted.
Este método funciona extremadamente bien. ¡¡Lo uso todo el tiempo con gran éxito!!
En resumen, esto explica cómo utilizar la clase de depuración NSZombie de Cocoa y la herramienta de línea de comando "malloc_history" para encontrar exactamente a qué objeto liberado se ha accedido en su código.
Nota al margen:
Ejecutar instrumentos y verificar si hay fugas no ayudará a solucionar problemas de EXC_BAD_ACCESS. Estoy bastante seguro de que las pérdidas de memoria no tienen nada que ver con EXC_BAD_ACCESS. La definición de fuga es un objeto al que ya no tiene acceso y, por lo tanto, no puede llamarlo.
ACTUALIZACIÓN: ahora uso Instrumentos para depurar fugas. Desde Xcode 4.2, elija Producto->Perfil y cuando se inicie Instrumentos, elija "Zombies".
Una señal EXC_BAD_ACCESS es el resultado de pasar un puntero no válido a una llamada al sistema. Recibí uno hoy con un programa de prueba en OS X; estaba pasando una variable no inicializada a pthread_join()
, lo cual se debió a un error tipográfico anterior.
No estoy familiarizado con el desarrollo de iPhone, pero deberías volver a verificar todos los punteros del búfer que estás pasando a las llamadas al sistema. Aumente el nivel de advertencia de su compilador por completo (con gcc, use las opciones -Wall
y -Wextra
). Habilite tantos diagnósticos en el simulador/depurador como sea posible.