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 problemas en el simulador de iPhone, también se depurará y ejecutará siempre que siga las instrucciones una por una. Tan pronto como lo deje correr nuevamente, presionaré 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ía una vez implementado en el dispositivo.
La mayoría de las respuestas a esta pregunta se refieren al EXC_BAD_ACCESS
error general , por lo que lo dejaré abierto como una trampa para el temido error de acceso incorrecto.
EXC_BAD_ACCESS
normalmente se produce como resultado de un acceso ilegal a la memoria. Puede encontrar más información en las respuestas a continuación.
¿Has encontrado la EXC_BAD_ACCESS
señal antes y cómo la manejaste?
fuente
Una causa importante de EXC_BAD_ACCESS es intentar acceder a los 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 usar 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:
La ejecución de instrumentos y la comprobación de fugas no ayudarán a solucionar 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 una 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 lance Instrumentos, elija "Zombis".
fuente
Una señal EXC_BAD_ACCESS es el resultado de pasar un puntero no válido a una llamada del sistema. Hoy recibí uno con un programa de prueba en OS X: estaba pasando una variable no inicializada
pthread_join()
, debido a un error tipográfico anterior.No estoy familiarizado con el desarrollo de iPhone, pero debe verificar dos veces todos los punteros de búfer que pasa a las llamadas del sistema. Sube el nivel de advertencia de tu compilador hasta el final (con gcc, usa las opciones
-Wall
y-Wextra
). Habilite tantos diagnósticos en el simulador / depurador como sea posible.fuente
En mi experiencia, esto generalmente es causado por un acceso ilegal a la memoria. Verifique todos los punteros, especialmente los punteros de objeto, para asegurarse de que estén inicializados. Asegúrese de que su archivo MainWindow.xib, si está utilizando uno, esté configurado correctamente, con todas las conexiones necesarias.
Si ninguna de esas comprobaciones en papel revela algo, y no sucede cuando se realiza un solo paso, intente localizar el error con las instrucciones NSLog (): espolvoree su código con ellas, muévalas hasta que aísle la línea que está causando el error. Luego establezca un punto de interrupción en esa línea y ejecute su programa. Cuando llegue al punto de ruptura, examine todas las variables y los objetos en ellas, para ver si algo no se ve como esperaba. Especialmente estaré atento a las variables cuya clase de objeto es algo que no esperaba. Si se supone que una variable contiene una UIWindow pero en su lugar tiene una NSNotification, el mismo error de código subyacente podría manifestarse de manera diferente cuando el depurador no está en funcionamiento.
fuente
Acabo de pasar un par de horas rastreando un EXC_BAD_ACCESS y descubrí que NSZombies y otros entornos no parecían decirme nada.
Para mí, fue una declaración estúpida de NSLog con especificadores de formato, pero no pasó ningún argumento.
Arreglado por
fuente
Los videos WWDC 2010 están disponibles para cualquier participante en el programa de desarrolladores de Apple. Hay un gran video: "Sesión 311 - Análisis avanzado de memoria con instrumentos" que muestra algunos ejemplos de uso de zombis en instrumentos y depuración de otros problemas de memoria.
Para obtener un enlace a la página de inicio de sesión, haga clic AQUÍ .
fuente
No es una respuesta completa, pero una situación específica en la que he recibido esto es cuando intento acceder a un objeto que 'murió' porque intenté usar la liberación automática:
Entonces, por ejemplo, en realidad estaba pasando esto como un objeto para 'notificar' (lo registré como oyente, observador, cualquier idioma que desee) pero ya había muerto una vez que se envió la notificación y obtendría el EXC_BAD_ACCESS. Cambiarlo
[[MyNetObject alloc] init]
y liberarlo más tarde, según corresponda, resolvió el error.Otra razón por la que esto puede suceder es, por ejemplo, si pasa un objeto e intenta almacenarlo:
Más adelante, cuando intente acceder a myObjectDefinedInHeader, puede tener problemas. Utilizando:
puede ser lo que necesitas Por supuesto, estos son solo un par de ejemplos de lo que me he encontrado y hay otras razones, pero pueden resultar escurridizas, así que las menciono. ¡Buena suerte!
fuente
Solo para agregar otra situación en la que esto puede suceder:
Tenía el código
Obviamente me había olvidado de asignar memoria para la cadena:
soluciona el problema
fuente
Otro método para detectar excepciones EXC_BAD_ACCESS antes de que ocurran es el analizador estático , en XCode 4+.
Ejecute el analizador estático con Producto> Analizar (shift + cmd + B). Al hacer clic en cualquier mensaje generado por el analizador, se superpondrá un diagrama en su fuente que muestra la secuencia de retenciones / liberaciones del objeto ofensor.
fuente
Me resulta útil establecer un punto de interrupción en objc_exception_throw. De esa forma, el depurador debería romperse cuando obtenga EXC_BAD_ACCESS.
Las instrucciones se pueden encontrar aquí Técnicas de depuración
fuente
Use la regla simple de "si no lo asignó o retuvo, no lo libere".
fuente
Cómo depurar EXC_BAD_ACCESS
Mira el enlace de arriba y haz lo que dice ... Solo algunas instrucciones rápidas para usar NSZombies
Ejecute la aplicación y luego de que falle (Debería mostrar "Interrumpido" en lugar de "EXC_BAD_ACCESS" ... verifique la Consola (Ejecutar> Consola) ... debería haber un mensaje que indique qué objeto estaba intentando acceder.
-Ben
fuente
He estado depurando y refactorizando código para resolver este error durante las últimas cuatro horas. Una publicación anterior me llevó a ver el problema:
Propiedad anterior: startPoint = [[DataPoint alloc] init]; startPoint = [DataPointList objectAtIndex: 0];
. . . x = startPoint.x - 10; // EXC_BAD_ACCESS
Propiedad después de: startPoint = [[DataPoint alloc] init]; startPoint = [[DataPointList objectAtIndex: 0] retener];
Adiós EXC_BAD_ACCESS
fuente
¡Espero que estés soltando la 'cuerda' cuando hayas terminado!
fuente
Olvidé regresar a mí mismo en un método init ...;)
fuente
Este es un excelente hilo. Aquí está mi experiencia: me equivoqué con la palabra clave de retención / asignación en una declaración de propiedad. Dije:
donde debería haber dicho
fuente
Encontré EXC_BAD_ACCESS en el iPhone solo mientras intentaba ejecutar un método C que incluía una gran matriz. El simulador pudo darme suficiente memoria para ejecutar el código, pero no el dispositivo (la matriz tenía un millón de caracteres, ¡así que era un poco excesivo!).
El EXC_BAD_ACCESS ocurrió justo después del punto de entrada del método y me confundió durante bastante tiempo porque no estaba cerca de la declaración de la matriz.
Quizás alguien más podría beneficiarse de mis dos horas de tirones de cabello.
fuente
Olvidé sacar un puntero no asignado de
dealloc
. Estaba obteniendo el exc_bad_access en mi rootView de un UINavigationController, pero solo a veces. Supuse que el problema estaba en rootView porque se estaba bloqueando a la mitad de su viewDidAppear {}. Resultó que solo sucedió después de que aparecí la vista con el mal lanzamiento de Dealloc {}, ¡y eso fue todo!"EXC_BAD_ACCESS" [Cambiando al proceso 330] No hay memoria disponible para programar ahora: no es seguro llamar a malloc
Pensé que era un problema donde estaba tratando de asignar ... no donde estaba tratando de liberar un no-alloc, ¡Oh!
fuente
Cómo trato con EXC_BAD_ACCESS
A veces siento que cuando se produce un error EXC_BAD_ACCESS, xcode mostrará el error en la clase main.m sin dar información adicional de dónde ocurre el bloqueo (a veces).
En esos momentos, podemos establecer un punto de interrupción excepcional en Xcode para que cuando se detecte una excepción, se coloque un punto de interrupción e íntimamente al usuario que el bloqueo ha ocurrido en esa línea
fuente
Las llamadas NSAssert () para validar los parámetros del método son bastante útiles para rastrear y evitar pasar nulos también.
fuente
acabo de tener este problema. Para mí, la razón fue eliminar un objeto administrado por CoreData e intentar leerlo luego desde otro lugar.
fuente
He estado depurando y refactorizando código para resolver este error durante las últimas cuatro horas. Una publicación anterior me llevó a ver el problema:
Propiedad antes:
Propiedad después de:
Adiós
EXC_BAD_ACCESS
Muchas gracias por tu respuesta. He estado luchando con este problema todo el día. ¡Eres increíble!
fuente
Solo para agregar
Lynda.com tiene un fantástico DVD llamado
y el Capítulo 6, Lección 3, trata de EXEC_BAD_ACCESS y de trabajar con Zombies.
Fue genial para mí entender, no solo el código de error, sino cómo puedo usar Zombies para obtener más información sobre el objeto lanzado.
fuente
Para verificar cuál puede ser el error
Use NSZombieEnabled.
Para activar la instalación NSZombieEnabled en su aplicación:
Elija Proyecto> Editar ejecutable activo para abrir la ventana de información ejecutable. Haz clic en Argumentos. Haga clic en el botón Agregar (+) en la sección "Variables para establecer en el entorno". Ingrese NSZombieEnabled en la columna Nombre y SÍ en la columna Valor. Asegúrese de que la marca de verificación para la entrada NSZombieEnabled esté seleccionada.
Encontré esta respuesta en iPhoneSDK
fuente
Me doy cuenta de que esto se preguntó hace algún tiempo, pero después de leer este hilo, encontré la solución para XCode 4.2: Producto -> Editar esquema -> Pestaña Diagnóstico -> Habilitar objetos zombi
Me ayudó a encontrar un mensaje enviado a un objeto desasignado.
fuente
Cuando tienes una recursión infinita, creo que también puedes tener este error. Este fue un caso para mí.
fuente
Incluso otra posibilidad: al usar bloques en las colas, puede suceder fácilmente que intente acceder a un objeto en otra cola, que ya se ha desasignado en este momento. Por lo general, cuando intenta enviar algo a la GUI. Si su punto de interrupción de excepción se establece en un lugar extraño, entonces esta podría ser la causa.
fuente
Lo entendí porque no estaba usando
[self performSegueWithIdentifier:sender:]
y-(void) prepareForSegue:(UIstoryboardSegue *)
correctofuente
No olvide el
@
símbolo al crear cadenas, tratandoC-strings
comoNSStrings
causaráEXC_BAD_ACCESS
.Utilizar este:
En vez de esto:
PS: normalmente cuando se rellenan contenidos de un
array
archivo con muchos registros.fuente
XCode 4 y superior, se ha hecho realmente simple con los instrumentos. Solo ejecuta Zombies en Instrumentos. Este tutorial lo explica bien: depuración de errores de exc_bad_access xcode
fuente