2009-01-22 8 views
6

Aquí está mi caso: tengo una vista de tabla que muestra los contactos. El botón Agregar en la barra de navegación se usa para cargar otra vista para la entrada de datos. Esta nueva vista tiene imágenes en el encabezado de la tabla, y cada celda de la tabla tiene UITextField o UITextView. Cuando presiono Cancelar, la vista se abre y se libera la memoria.Desarrollo de iPhone - error EXC_BAD_ACCESS sin traza de pila

aquí está mi problema: cuando abra la interfaz "Añadir", proporcionar un valor en cualquiera de los UITextField o UITextView, y pulse "Cancelar" para volver a la vista padre, me sale un error EXC_BAD_ACCESS. Cuando lo rastrear, el "Agregar controlador" llama a dealloc correctamente, pero después del [super dealloc] cuando presiono Continuar, arroja este error. Sólo esto, no hay rastro, aunque estoy usando NSZombieEnabled. Cuando corro el código con los instrumentos, no consigo cualquier error :(

Espero estar claro en la explicación del tema. Cualquier punteros? Gracias.

+0

El problema desaparece mágicamente cuando quito [liberación tableView] de mi El método dealloc de la clase del controlador "Add Contact". Pero debería liberar el objeto tableView, ¿verdad? Aunque estoy usando el archivo nib, e hice de tableView un 'IBOutlet'. – Mustafa

+1

No, no deberías. La regla para recordar es 'Si no lo asignó explícitamente, lo copió o lo retuvo, entonces no lo libera explícitamente'. –

Respuesta

8

La causa más común de este error es cuando suelta un objeto y algún otro mecanismo intenta acceder/liberar/desasignarlo más tarde.

Cada vez que recibo un informe de un error EXC_BAD_ACCESS, mi primera recomendación es recorrer el código para determinar qué línea lo está causando, y luego para buscar cualquier llamada explícita [object release] que haga referencia a ese objeto. Coméntelos uno por uno para encontrar dónde puede haber salido mal (y, por supuesto, asegúrese de que El objeto se lanza correctamente más tarde).

Si la línea no le ayuda a determinar qué objeto (s) está causando el problema, comience a buscar a través de sus llamadas [object release], y asegúrese de no liberar objetos demasiadas veces por accidente o soltando objetos que no son de su propiedad.

Esto conduce a una buena pauta general en cuanto a release en Objective-C:

Si es el propietario de un objeto (o asignar retenerlo), que lo suelte. Si no es el propietario (vino a través de un método de conveniencia o alguien más lo asignó), no lo libera.

(Via Memory Management with Objective C/Cocoa/iPhone, que también tiene algunos buenos consejos.)

1

La regla general es que nada se crea, que necesita para gestionar (retener/release). Cualquier cosa que salga de un NIB, generalmente no se debe liberar en el código.

3

Ponga [super dealloc] como la última declaración del método de clase dealloc. Obtendrás este comportamiento cuando trates a la súper clase primero.

6

Aunque esto suele ser el resultado de una memoria mal administrada, puede suceder por otros motivos (y será más difícil de depurar que simplemente activar NSZombieEnabled). Por ejemplo, si no proporciona la cantidad correcta de argumentos a una cadena de formato (es decir, al depurar otro problema con NSLog), podría terminar sin rastro de pila incluso con todos los argumentos de depuración habilitados. Afortunadamente, puede usar GDB dentro de Xcode en restore the stack trace to a previous state.

En la consola GDB debería ver las instrucciones que bloquearon su programa. Ubique la última instrucción de devolución exitosa antes de la que falló.Debe ser algo como esto:

je 0x986cef35 <objc_msgSend+117> 

Nota el valor hexadecimal y ejecutar lo siguiente en GDB:

set $eip = 0x986cef35 
stepi 
where 

Debe (con suerte) tienen un seguimiento de pila más informativo ahora.

Source (igual que el siguiente enlace)

+0

El [enlace] (http://www.mulle-kybernetik.com/weblog/2010/07/exc_bad_access_and_no_stack_tr.html) no funciona. Aquí está el [actualizado] (http://www.mulle-kybernetik.com/weblog/2010/exc_bad_access_and_no_stack_tr.html) uno – BLC

1

Las declaraciones anteriores que no se debe liberar objetos NIB se contradicen por Apple: ver here, donde dice que los objetos para los que tiene una salida deben ser liberados en dealloc , y también que debe asegurarse de establecer la referencia del objeto en cero después.

Descargo de responsabilidad: Soy un novato de programación de iPhone, aunque he estado programando durante mucho tiempo.

2

La respuesta de Cameron Spickert es un poco obsoleta, ya que Xcode usa lldb ahora en lugar de gdb. El enlace al artículo fuente también está muerto.

Lo mismo se puede hacer en lugar simplemente con el siguiente comando LLDB:

(lldb) thread backtrace 

Esto mostrará el bt para el subproceso actual. Si desea cambiar el hilo del que desea obtener el bt, seleccione el marco y obtener de esta manera:

(lldb) thread list 
(lldb) thread select 2 
(lldb) thread backtrace 

Si desea replicar el comportamiento exacto de la respuesta de Cameron Spickert, utilice los siguientes comandos:

(lldb) expr unsigned int $eip = 0x1979c81d4 
(lldb) stepi 
(lldb) thread backtrace 

Source 1

Source 2

Cuestiones relacionadas