Romper en EXC MAL ACCESO en XCode?


Soy nuevo en el desarrollo de iPhone y XCode en general y no tengo idea de cómo comenzar a solucionar problemas con una señal EXC_BAD_ACCESS. ¿Cómo puedo hacer que XCode se rompa en la línea exacta que está causando el error?


Parece que no puedo hacer que XCode se detenga en la línea que causa el problema, pero sí veo las siguientes líneas en mi consola de depuración:

Dom Oct 25 15: 12: 14 jasonsmacbook Proyecto de prueba[1289] : Cgcontextsetstrokecolor con color: contexto no válido

Dom Oct 25 15: 12: 14 jasonsmacbook Proyecto de prueba[1289] : CGContextSetLineWidth: contexto inválido

Dom Oct 25 15: 12: 14 jasonsmacbook Proyecto de prueba[1289] : CGContextAddPath: contexto no válido

Dom Oct 25 15: 12: 14 jasonsmacbook Proyecto de prueba[1289] : CGContextDrawPath: contexto no válido

2009-10-25 15:12:14.680 LanderTest[1289:207] *** -[CFArray objectAtIndex:]: mensaje enviado a instancia desasignada 0x3c4e610

Ahora, estoy tratando de dibujar a la contexto recupero de UIGraphicsGetCurrentContext() y paso al objeto con el que quiero dibujar.


Más prueba y error de depuración y encontré que un NSMutableArray tengo una propiedad para en mi clase era un zombie. Entré en la función init para la clase y aquí está el código que estaba usando:

if ((self = [super init])) {
        NSMutableArray *array = [NSMutableArray array];
        self.terrainBlocks = array;
        [array release];
    }
    return self;    
}

Eliminé la línea [array release] y ya no me da la señal EXC_BAD_ACCESS, pero ahora estoy confundido acerca de por qué funciona esto. Pensé que cuando usé la propiedad, la retuvo automáticamente para mí, y así que debería liberarlo desde dentro init para que no tenga una fuga. Estoy completamente confundido sobre cómo funciona esto y todas las guías y preguntas de Stackoverflow que he leído solo me confunden más sobre cómo establecer propiedades dentro de mi método init. No parece haber consenso sobre cuál es el mejor camino.

Author: jasonh, 2009-10-26

10 answers

Para cualquier error EXC_BAD_ACCESS, normalmente intenta enviar un mensaje a un objeto liberado. La MEJOR manera de rastrearlos es usar NSZombieEnabled.

Esto funciona nunca liberando un objeto, sino envolviéndolo como un "zombi" y estableciendo una bandera dentro de él que dice que normalmente habría sido liberado. De esta manera, si intenta acceder de nuevo, todavía sabe lo que era antes de cometer el error, y con este poco de información, puede por lo general, dar marcha atrás para ver cuál era el problema.

Ayuda especialmente en hilos de fondo cuando el depurador a veces craps hacia fuera en cualquier información útil.

SIN embargo, es MUY IMPORTANTE TENER EN CUENTA que necesita asegurarse al 100% de que esto solo esté en su código de depuración y no en su código de distribución. Debido a que nunca se libera nada, su aplicación se filtrará y filtrará y filtrará. Para recordarme que haga esto, puse este registro en mi appdelegate:

if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
  NSLog(@"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");

Si necesita ayuda para encontrar el line, Haga un Build-and-Debug (CMD-Y ) en lugar de un Build-and-Run ( CMD-R). Cuando la aplicación se bloquea, el depurador le mostrará exactamente qué línea y en combinación con NSZombieEnabled, debería poder averiguar exactamente por qué.

 84
Author: coneybeare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-25 21:22:49

Acerca de su matriz. La línea

NSMutableArray *array = [NSMutableArray array];

En realidad no le da un objeto retenido sino más bien un objeto de autorelease. Probablemente se mantiene en la siguiente línea, pero entonces no debe liberarlo en la tercera línea. Ver esto

Esta es la regla fundamental:

Usted toma posesión de un objeto si lo crea utilizando un método cuyo nombre comienza con "alloc" o " new " o contiene "copy" (por ejemplo, alloc, newObject o mutableCopy), o si le envía un mensaje de retención. Usted es responsable de renunciar a la propiedad de los objetos que posee utilizando release o autorelease. En cualquier otro momento que reciba un objeto, no debe liberarlo.

 17
Author: epatel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-25 23:04:09

En Xcode 4, puede habilitar Zombies haciendo clic en el menú desplegable Scheme (arriba a la izquierda, a la derecha junto al botón stop) -> Editar Scheme -> Pestaña Diagnostics -> Habilitar Objetos Zombie

 10
Author: snez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-10 12:37:08

Xcode/gdb siempre se rompe en EXC_BAD_ACCESS, solo necesita trabajar su camino hacia arriba en la pila de llamadas para encontrar el código que lo activó.

Tenga en cuenta que este tipo de errores a menudo ocurren con objetos autoreleased, lo que significa que la causa última del problema no estará en la pila de llamadas que activó EXC_BAD_ACCESS. Es entonces cuando NSZombieEnabled y NSAutoreleaseFreedObjectCheckEnabled se vuelven útiles.

 7
Author: Darren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-25 23:01:37

Una nueva respuesta a un hilo antiguo... en XCode 4 la forma más efectiva de diagnosticar excepciones EXC_BAD_ACCESS es usar Instrumentos para perfilar su aplicación (desde XCode haga clic en Producto/Perfil y elija Zombies). Esto le ayudará a identificar los mensajes enviados a objetos desasignados.

 5
Author: Jonathan Moffatt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-11-15 11:24:54

De las clases de Stanford CS193P: si agrega un punto de interrupción (manualmente, editando puntos de interrupción) para el símboloobjc_exception_throw puede obtener una imagen mucho mejor de lo que salió mal: dejar que las cosas procedan al punto donde el depurador se detiene por sí mismo tiende a oscurecer las cosas y arruinar el seguimiento de la pila. Cuando se detiene en objc_exception_throw, a menudo puede mirar hacia atrás exactamente qué acceso / operación causó su problema.

 2
Author: Adam Eberbach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-25 22:23:46

Otro enfoque útil es establecer puntos de interrupción que se activarán directamente después de que ocurra la excepción:

Abra la ventana de puntos de interrupción (Run-Show-Breakpoints) y agregue dos puntos de interrupción simbólicos llamados "objc_exception_throw" y "[NSException raise] "

Desde: http://blog.emmerinc.be/index.php/2009/03/19/break-on-exception-in-xcode/

 2
Author: Frank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-23 04:39:14

Solo quería agregar para los demás que vienen de una web, buscando soluciones para el mismo error pero con error diferente. En mi caso obtuve el mismo error cuando traté de instanciar NSDictionary con error tipográfico en el nombre de la clave donde olvidé agregar " @ " delante de mi clave:

NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys: myObj1, @"goodKey", myObj2, "badkey @ is missing in front", nil];
 1
Author: Centurion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-13 11:59:07

Espero no haberme perdido una respuesta idéntica, pero he encontrado que es posible que algunos proyectos arrojen este error debido a que se ejecutan en simuladores para versiones anteriores de iOS que pueden ser incompatibles con una dependencia o marco de trabajo del proyecto. Estuve persiguiendo uno de estos durante demasiado tiempo antes de darme cuenta de que estaba sucediendo en las versiones de simuladores más antiguos, como el iPhone 4S, la aplicación ni siquiera se suponía que intentara soportar.

Habría sido bueno haber recibido un mensaje de error más detallado, pero me imagino que esa es la responsabilidad del marco donde se originó... En cualquier caso, este es un aterrizaje de búsqueda bastante común y tal vez esto ayudará a alguien haciendo el tonto tan mal como me encontré a mí mismo.

 1
Author: Thomas Allenbaugh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-23 06:29:03

Antes de habilitar zombies, recomiendo primero deshacerse de todas las advertencias (si tiene alguna). Cosas simples como una función no void sin returnpueden causar este error. Si no tiene advertencias, proceda como sugieren las otras respuestas.

 0
Author: user2387149,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-26 16:55:21