2011-04-13 5 views
6

¡Ayuda, he estado pirateando esto durante semanas ahora! Tengo esta aplicación que estoy desarrollando en el simulador, y he hecho muchas cosas sobre la interfaz de usuario, solo estoy llegando a la parte interesante con datos. Comenzó inmediatamente después del lanzamiento, aproximadamente el 90% del tiempo que lo ejecuto, aumentará la excepción EXC_BAD_ACCESS.Cómo depurar EXC_BAD_ACCESS en la aplicación iPhone cuando no puedo determinar la causa?

He comentado todos mis mensajes de lanzamiento, e incluso he agregado algunos mensajes de retención para asegurarme de que no sea algo que se haya liberado. Lo extraño es que a veces algo que hago en el código lo hace funcionar, luego funciona hasta que hago otro cambio de código. Luego, comento el nuevo código que agregué, y aún falla.

He leído probablemente una docena de artículos en la web sobre esto, he intentado con las cosas que sugieren. He establecido puntos de interrupción y todavía no puedo descubrir dónde está. Cuando hago clic en la pila de llamadas en el depurador, el único lugar que muestra el código fuente es el nivel inferior, que es el principal.

El depurador tiene esta pila, pero eso fluctúa un poco cada vez que se bloquea. La naturaleza inconsistente me dice que hay algo de memoria que se está liberando automáticamente, pero no tengo idea de cómo averiguar qué.

0 objc_msgSend 
1 ?? 
2 _CFAutoReleasePoolPop 
3 -[NSAutoReleasePool release] 
4 _UIApplicationHandleEvent 
5 PurpleEventCallback 
6 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ 
7 __CFRunLoopDoSource1 
8 __CFRunLoopRun 
9 CFRunLoopRunSpecific 
10 CFRunLoopRunInMode 
11 -[UIApplication _run] 
12 UIApplicationMain 
13 main 

algunos datos más:

  • puse NSZombieEnabled, que no lo hicieron hacer una diferencia en la consola de salida
  • me encontré con instrumentos utilizando el perfil fugas, didn' t muestra cualquier fugas

Respuesta

10

querrá habilitar objetos zombie en su código, y Comprobar los objetos creados automáticamente y, tal vez, habilitar la depuración ayudará.

Agregué tres variables de entorno.

  • NSZombieEnabled
  • NSAutoreleaseFreedObjectCheckEnabled
  • NSDebugEnabled

todos ellos están situados en SÍ

Aquí hay un enlace con el camino que tomé.

http://www.codza.com/how-to-debug-exc_bad_access-on-iphone

si está utilizando XCode 4 a continuación, va a agregar estos en la sección Argumentos de la popover Editar Esquemas.

Otra cosa a tener en cuenta es que solo debe liberar o soltar automáticamente los objetos que retenga. Mantiene un retener en los siguientes objetos.

  • Cualquier objeto que alloc [alloc NSObject]
  • Cualquier objeto obtenido usando el nuevo comando estática [NSObject nuevo]
  • Cualquier objeto que retiene de forma explícita [MyObject retener]
  • Cualquier copia de un objeto [ copia myObject]
  • Cualquier propiedad con el atributo de retención o copia @property (retención) NSString * myProperty;

si envía una liberación automática a cualquier objeto que no sea este, podría terminar al azar con este y otros errores.

comúnmente solté objetos y luego los puse en cero, de esa manera si los lanzo más tarde, no tendré ningún problema porque si sueltas el cero automáticamente, obtienes nada.

NSObject *myObject = [incomingObject retain]; 
// Do something with the object. 
[myObject autorelease]; 
[myObject autorelease]; // This line will end in an error down the line when the object is released past 0, or when the release pool is drained. 
myObject = nil; 
[myObject release]; // This line will do nothing. no error, no effect. 
+0

Gracias, Jason. ¿Supongo que te refieres a NSZombieEnabled? No hizo una diferencia en la salida de la consola. Agregué al ejecutable la variable NSAutoreleaseFreedObjectCheckEnabled = YES, tampoco marcó la diferencia en la consola. ¿Qué estoy buscando con eso? –

+0

Estaba teniendo los mismos problemas que tú, miré por todas partes porque la ruta de pila no era útil. Terminé con tres variables de entorno. (NSZombieEnabled, NSAutoreleaseFreedObjectCheckEnabled, NSDebugEnabled) tal vez el último sea útil ... También hay solo unos pocos objetos que deberías lanzar. Actualizaré la publicación para incluirlos. –

+0

Encontré esas variables en Debug.h, pero configurarlas en el inspector ejecutable y reiniciar el simulador no pareció marcar la diferencia. Esto tiene que ser solucionable. Tengo una liberación automática en un tableView: cellForRowAtIndexPath: en la vista que genera para la celda, pero la eliminación del mensaje de liberación automática no previno el bloqueo. –

0

La causa más probable es la adición de un cubo de basura o un objeto ya liberado a la piscina Autorelease - tal vez en esa función PurpleEventCallback?

+0

¿Cómo agrego un objeto al grupo de autorrelease, es eso al enviar un mensaje de versión? Comenté todos mis mensajes de lanzamiento en toda la aplicación para asegurarme de que no estuvieran demasiado abiertos. –

+0

esa es una buena manera de comenzar una fuga. y la liberación no es normalmente la culpable, a menos que comiences con un objeto liberado automáticamente ... prueba a contar los retenes y liberaciones en los objetos que tienes. asegúrese de que coincidan. –

+0

Todas las retenciones que tengo son asignaciones para retener propiedades. Traté de agregar algunas partes para garantizar la vida más allá de la función, pero como no hicieron desaparecer el error, las eliminé. Perdónenme, soy nuevo en el desarrollo de iPhone/Mac, pero si asigno una propiedad retener, la liberación se produce cuando ese objeto se desasigna, ¿verdad? Debo agregar, el bloqueo se produce de inmediato en la aplicación, después de que se inicializan las barras de pestañas/controladores de navegación, y antes de que pueda tocar nada. No sé lo que hice para presentarlo. –

Cuestiones relacionadas