tutorial ios cocoa-touch

ios - cocoa touch tutorial



EXC_BAD_ACCESS seƱal recibida (30)

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 se ejecutará siempre y cuando siga las instrucciones de una en una. Tan pronto como lo deje correr nuevamente, golpearé la señal EXC_BAD_ACCESS .

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 desplegado en el dispositivo.

La mayoría de las respuestas a esta pregunta tienen que ver con el error general EXC_BAD_ACCESS , por lo que lo dejaré abierto como un problema general para el error de acceso incorrecto temido.

EXC_BAD_ACCESS normalmente se lanza como resultado de un acceso de memoria ilegal. Puedes encontrar más información en las respuestas a continuación.

¿Te has encontrado con la señal EXC_BAD_ACCESS antes, y cómo la EXC_BAD_ACCESS ?


Acabo de pasar un par de horas rastreando un EXC_BAD_ACCESS y descubrí que NSZombies y otras variables de entorno no parecían decirme nada.

Para mí, era una declaración estúpida de NSLog con especificadores de formato, pero no se aprobaron argumentos.

NSLog(@"Some silly log message %@-%@");

Arreglado por

NSLog(@"Some silly log message %@-%@", someObj1, someObj2);


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 proporcionar información adicional sobre dónde ocurre el bloqueo (a veces).

En esos momentos, podemos establecer un Punto de Interrupción Excepcional en Xcode para que cuando se capture la excepción se coloque un punto de interrupción e intimide directamente al usuario que la falla ocurrió en esa línea


Cuando tienes una recursión infinita, creo que también puedes tener este error. Este fue un caso para mí.


En mi experiencia, esto generalmente es causado por un acceso de memoria ilegal. Compruebe 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á usando uno, esté configurado correctamente, con todas las conexiones necesarias.

Si ninguna de esas comprobaciones en el papel se convierte en algo, y no sucede cuando se realiza un solo paso, intente localizar el error con las declaraciones de NSLog (): rocíe su código con ellas, moviéndolas 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 interrupción, examine todas las variables y los objetos que contiene, para ver si algo no se ve como esperaba. Especialmente vigilaría las variables cuya clase de objeto es algo que no esperaba. Si se supone que una variable debe contener una UIWindow pero en su lugar tiene una NSNotification, el mismo error de código subyacente podría manifestarse de una manera diferente cuando el depurador no está en funcionamiento.


Encontré EXC_BAD_ACCESS en el iPhone solo al intentar ejecutar un método C que incluía una gran matriz. El simulador fue capaz de 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.

Tal vez alguien más podría beneficiarse de mi par de horas de tirar el pelo.


Espero que estés liberando la ''cadena'' cuando hayas terminado!


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:

@property (nonatomic, assign) IBOutlet UISegmentedControl *choicesControl; @property (nonatomic, assign) IBOutlet UISwitch *africaSwitch; @property (nonatomic, assign) IBOutlet UISwitch *asiaSwitch;

donde debería haber dicho

@property (nonatomic, retain) IBOutlet UISegmentedControl *choicesControl; @property (nonatomic, retain) IBOutlet UISwitch *africaSwitch; @property (nonatomic, retain) IBOutlet UISwitch *asiaSwitch;


He estado depurando y refactorizando el código para resolver este error durante las últimas cuatro horas. Un post arriba me llevó a ver el problema:

Propiedad antes:

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] retain];

Adiós EXC_BAD_ACCESS

Muchas gracias por tu respuesta. He estado luchando con este problema todo el día. ¡Eres increíble!


He estado depurando y refactorizando el código para resolver este error durante las últimas cuatro horas. Un post arriba me llevó a ver el problema:

Propiedad antes: 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] retain];

Adiós EXC_BAD_ACCESS


Incluso otra posibilidad: mediante el uso de bloques en colas, puede suceder fácilmente que intente acceder a un objeto en otra cola, que ya se ha desasignado en este momento. Normalmente cuando intentas 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.


Las llamadas a NSAssert () para validar los parámetros del método son bastante útiles para rastrear y evitar también pasar nils.


Lo obtuve porque no estaba usando [self performSegueWithIdentifier:sender:] y -(void) prepareForSegue:(UIstoryboardSegue *) right


Los videos de la WWDC 2010 están disponibles para todos los participantes en el programa para desarrolladores de Apple. Hay un gran video: "Sesión 311 - Análisis avanzado de memoria con instrumentos" que muestra algunos ejemplos de cómo usar zombies en instrumentos y depurar otros problemas de memoria.

Para un enlace a la página de inicio de sesión, haga clic HERE .


Me di cuenta de que esto se me preguntó hace algún tiempo, pero después de leer este hilo, encontré la solución para XCode 4.2: Producto -> Esquema de edición -> Pestaña Diagnóstico -> Habilitar objetos de Zombie

Me ayudó a encontrar un mensaje que se envía a un objeto desasignado.


Me parece útil establecer un punto de interrupción en objc_exception_throw. De esa manera, el depurador debería interrumpirse cuando obtenga el EXC_BAD_ACCESS.

Las instrucciones se pueden encontrar aquí. DebuggingTechniques


No es una respuesta completa, pero una situación específica en la que recibí esto es cuando trato de acceder a un objeto que ''murió'' porque intenté usar el autorelease:

netObjectDefinedInMyHeader = [[[MyNetObject alloc] init] autorelease];

Así, por ejemplo, en realidad pasaba esto como un objeto para ''notificar'' (lo registré como un oyente, un observador, el idioma que quiera) pero ya había muerto una vez que se envió la notificación y obtuve el EXC_BAD_ACCESS. Cambiándolo a [[MyNetObject alloc] init] y liberándolo más tarde, según sea apropiado, se resolvió el error.

Otra razón por la que esto puede suceder es, por ejemplo, si pasa un objeto y trata de almacenarlo:

myObjectDefinedInHeader = aParameterObjectPassedIn;

Más adelante, cuando intentes acceder a myObjectDefinedInHeader, puedes tener problemas. Utilizando:

myObjectDefinedInHeader = [aParameterObjectPassedIn retain];

puede ser lo que necesites. Por supuesto, estos son solo un par de ejemplos de lo que me he encontrado y hay otras razones, pero pueden ser difíciles de encontrar, así que las menciono. ¡Buena suerte!


No olvide el símbolo @ cuando cree cadenas, tratar C-strings como NSStrings causará EXC_BAD_ACCESS .

Utilizar esta:

@"Some String"

En vez de esto:

"Some String"

PD: normalmente al rellenar contenidos de una array con muchos registros.


Olvidé volver a mí mismo en un método de inicio ...;)


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 infractor.


Para comprobar cuál podría ser el error.

Utilice NSZombieEnabled.

Para activar la instalación NSZombieEnabled en su aplicación:

Elija Proyecto> Editar archivo ejecutable activo para abrir la ventana de información ejecutable. Haga clic en Argumentos. Haga clic en el botón Agregar (+) en la sección "Variables que se establecerán 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


Por su descripción, sospecho que la explicación más probable es que tiene algún error en la administración de su memoria. Usted dijo que ha estado trabajando en el desarrollo del iPhone durante algunas semanas, pero no si tiene experiencia con el Objetivo C en general. Si ha venido de otro fondo, puede tomar un poco de tiempo antes de que realmente internalice las reglas de administración de memoria, a menos que haga un gran punto de ello.

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 propietario de la memoria y debe liberarla cuando haya terminado.

Pero si obtiene algo de casi cualquier otra cosa, incluidos los métodos de fábrica (por ejemplo, [NSString stringWithFormat] ), tendrá una referencia de autorelease, lo que significa que podría ser publicado en otro momento por otro código, por lo que es vital eso si necesita mantenerlo más allá de la función inmediata que lo retiene. Si no lo hace, la memoria puede permanecer asignada mientras la está utilizando o liberarse, pero casualmente 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.


Se olvidó de sacar un puntero no asignado de dealloc . Obtuve el exc_bad_access en mi rootView de un UINavigationController, pero solo algunas veces. Asumí que el problema estaba en el rootView porque se estaba estrellando a la mitad de su viewDidAppear {}. Resultó que solo sucedía después de que abriera la vista con la versión mala de dealloc {}, ¡y eso fue todo!

"EXC_BAD_ACCESS" [Cambio al proceso 330] No hay memoria disponible para programar ahora: no es seguro llamar a malloc

Pensé que era un problema en el que estaba tratando de asignar ... no en el que estaba tratando de liberar un no-asignar, D''oh!


Solo para agregar

Lynda.com tiene un fantástico DVD llamado

iPhone SDK Essential Training

y el Capítulo 6, Lección 3 se trata de EXEC_BAD_ACCESS y de trabajar con Zombies.

Fue genial para mi entender, no solo el código de error sino también cómo puedo usar Zombies para obtener más información sobre el objeto liberado.


Solo para agregar otra situación donde esto pueda suceder:

Yo tenía el código:

NSMutableString *string; [string appendWithFormat:@"foo"];

Obviamente me había olvidado de asignar memoria para la cadena:

NSMutableString *string = [[NSMutableString alloc] init]; [string appendWithFormat:@"foo"];

arregla el problema


Una causa importante de EXC_BAD_ACCESS es el intento de acceder a los objetos liberados.

Para averiguar cómo solucionar este problema, lea este documento: DebuggingAutoReleasePool

Incluso si no cree que esté "liberando objetos de liberación automática", esto se aplicará en su caso.

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 comandos "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 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 inicie Instruments, elija "Zombies".


Una señal EXC_BAD_ACCESS es el resultado de pasar un puntero no válido a una llamada del sistema. Recibí uno más temprano hoy con un programa de prueba en OS X: estaba pasando una variable sin inicializar a pthread_join() , que se debió a un error tipográfico anterior.

No estoy familiarizado con el desarrollo de iPhone, pero debería verificar dos veces todos los punteros de búfer que está pasando a las llamadas al sistema. Suba el nivel de advertencia de su compilador hasta el final (con gcc, use las opciones -Wall y -Wextra ). Habilite tantos diagnósticos en el simulador / depurador como sea posible.


Use la regla simple de "si no lo asignó o no lo conservó, no lo libere".



acabo de tener este problema. Para mí, la razón era eliminar un objeto administrado CoreData y tratar de leerlo luego desde otro lugar.


Cómo depurar EXC_BAD_ACCESS

Echa un vistazo al enlace de arriba y haz lo que dice ... Solo algunas instrucciones rápidas para usar NSZombies

Ejecute la aplicación y después de que falle (debería mostrar "Interrumpido" en lugar de "EXC_BAD_ACCESS" ... verifique la Consola (Ejecutar> Consola) ... debería haber un mensaje que diga a qué objeto intentaba acceder.

-Ben