2012-02-08 3 views
6

Me estoy quedando sin ideas. Recibo un EXC_BAD_ACCESS en un proyecto usando ARC. De acuerdo con el depurador está dentro de main(). NSZombieEnabled está configurado en SÍ, pero no veo ninguna pila de llamadas o Clase/Tipo ni nada. Lo mismo para el Inspector/Perfil. Todo lo que obtengo es "tiempo de espera de la sesión" un tiempo después de que la aplicación se bloquee.EXC_BAD_ACCESS dentro de main() con ARC pero no hay ninguna pista sobre el error

Y es difícil de localizar dentro de mi código.

me he fijado como rastros

NSLog(@"CrashLog: <%@:%@:%d:%s>", NSStringFromClass([self class]), 
NSStringFromSelector(_cmd), __LINE__, __FILE__); 

todo mi código en la silueta de la mano y la salida de los métodos, pero todavía no se identificó ningún patrón útil. Todo lo que puedo ver es que todos mis métodos en cuestión ya se han dejado cuando se lanza el EXC_BAD_ACCESS.

¿Alguna idea sobre cómo aislar el problema?

Tim sugirió utilizar la traza inversa (bt) en gdb. El resultado es:

#0 0x0be87580 in TI::Favonius::BeamSearch::choose_hit_test_node() 
#1 0x0be87b5f in TI::Favonius::BeamSearch::update_for_touch() 
#2 0x0be8ee32 in TI::Favonius::StrokeBuildManager::update_search_for_touch() 
#3 0x0be8f58f in TI::Favonius::StrokeBuildManager::key_down_or_drag_hit_test_for_UI() 
#4 0x0be6ba8b in TIInputManagerZephyr::simulate_touches_for_input_string() 
#5 0x0be7e5d9 in -[TIKeyboardInputManagerZephyr candidates]() 
#6 0x00678345 in -[UIKeyboardImpl generateAutocorrectionReplacements:]() 
#7 0x007dcaec in __71-[UITextInteractionAssistant scheduleReplacementsForRange:withOptions:]_block_invoke_0() 
#8 0x007f6db2 in -[UITextSelectionView calculateAndShowReplacements:]() 
#9 0x00e255fd in __NSFireDelayedPerform() 
#10 0x01a03976 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__() 
#11 0x01a03417 in __CFRunLoopDoTimer() 
#12 0x019667e0 in __CFRunLoopRun() 
#13 0x01965dd4 in CFRunLoopRunSpecific() 
#14 0x01965ceb in CFRunLoopRunInMode() 
#15 0x01ccb879 in GSEventRunModal() 
#16 0x01ccb93e in GSEventRun() 
#17 0x0050d38b in UIApplicationMain() 
#18 0x000033e0 in main (argc=1, argv=0xbffff5fc) at /Users/Hermann/AppDev/fcApp/fcApp/main.m:16 

Respuesta

12

Todavía hay formas de obtener EXC_BAD_ACCESS con ARC. Algunos de los que me encontré con

  1. Si usted está haciendo algo en el que hacer un objeto de forma asíncrona y le devuelve la llamada - usted tiene que asegurarse de mantener una referencia a él en alguna parte o ARC permite que se abra. Un ejemplo es el UIImagePicker: no puede simplemente crear una variable de selector de imagen local y llamarla (y luego soltarla cuando le devuelva la llamada): debe crear una propiedad y conservarla

  2. If no siempre usas propiedades para aferrarte a él, podrías tener problemas - ARC usa la presencia de personas fuertes y débiles para saber qué hacer; si usas un ivar en su lugar, puedes engañar al ARC (no al 100%) seguro de esto). Una manera fácil de asegurarse de no hacer esto es usar @synthesize var = _var en lugar de dejar que la propiedad e ivar tengan el mismo nombre. De esta forma, si olvida self.var = obj y solo usa var = obj, se quejará.

  3. me encontré con un error en los gestos y las pestañas - las vistas de fichas no retener los gestos añadidos por IB - Me documentados aquí

Crash when using gesture recognizers in StoryBoard

En estos casos Zombies debería ayudar, por lo que no ayudar significa que probablemente no está causando prematuramente una liberación. Lo más probable es que esté borrando la memoria: verificaría todos los moldes y en cualquier lugar en el que utilice matrices integradas o punteros que no sean objetos para asegurarse de que no salga de los límites. Guardia Malloc puede ayudar

https://developer.apple.com/library/ios/#documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html

+0

Gracias Lou. Para 1. Estoy haciendo eso con las solicitudes http asincrónicas. Sin embargo, estoy bastante seguro de cancelar todas las conexiones abiertas dentro del método de depuración de los objetos solicitantes. Sin embargo, lo verificaré dos veces. Para 2 .: Gracias. No voy a verificar si estaba usando self.var en todos los casos relevantes. 3. no debería aplicarse a mi aplicación en absoluto. Sin embargo, puede ser un poco más específico en "guardia malloc". Esto es una novedad para mí o realmente no entendí lo que querías decir. (El inglés no es mi lengua materna). Gracias hasta ahora. –

+0

Siga el enlace para la ayuda de Guard Malloc. Hace que el montón sea más sensible a los problemas. –

+0

Esto no fue directamente helpfu. Sin embargo, siguiendo el consejo se redujo significativamente la ventana oportuna. Es mucho más fácil encontrar alguna causa raíz si tienes una idea, al menos, qué mirar o para qué. Estás ejecutando un gran blog. :) –

0

Intente ejecutar su aplicación con instrumentos (Producto> Perfil) y elija la plantilla Fugas. Podría darle pistas sobre dónde está el error. More information here

+0

Lo siento, no mencioné que ya lo hice. Gracias de cualquier manera. –

0

Suena como usted no tiene un conjunto excepción de punto de interrupción. Xcode no crea uno por defecto. Abra el Navegador de puntos de interrupción (cmd + 6), haga clic en el signo + en la esquina inferior izquierda y elija "Agregar punto de interrupción de excepción" en el menú que aparece. Haga clic en "Listo" y encontrará que ahora se está rompiendo cerca de donde se encuentra el problema.

Sin esto, a menudo encontrará que el depurador lo coloca en main sin una pista en el rastro de la pila sobre cómo llegó allí.

+0

Gracias. Tienes razón. Intentaremos hacerlo. –

+1

No, eso no me trajo más. Sin cambios en absoluto. –

1

Bien, finalmente lo conseguí - nealy.

Aún no sé qué detalle era incorrecto. Finalmente descubrí que el problema estaba relacionado con un UITextView. Originalmente, la vista de texto no estaba destinada a ser editable. Pero quería recibir eventos táctiles. así que follwed uno de los Hiere aconseja dada: (iPhone) How to handle touches on a UITextView? Asigné 'auto' (una subclase UIViewController) como delegado del UITextView y apenas implementado algunas protocolo de esta manera:

- (BOOL)textViewShouldBeginEditing:(UITextView *)textView{ 
    [self userShow:nil]; //Within this method a subsequent UIViewController subclass/object is created and pushed. 
    return FALSE; 
} 

- (BOOL)textViewShouldEndEditing:(UITextView *)textView{ 
    return TRUE; 
} 

- (void)textViewDidBeginEditing:(UITextView *)textView{ 
    return; 
} 

- (void)textViewDidEndEditing:(UITextView *)textView{ 
    return; 
} 


- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{ 
    return TRUE; 
} 

- (void)textViewDidChange:(UITextView *)textView{ 
    return; 
} 

- (void)textViewDidChangeSelection:(UITextView *)textView{ 
    return; 
} 

La intención era evitar realidad edición pero recibe el evento cuando un usuario toca el área de UITextView e invoca alguna acción. En este caso, se creó un controlador de vista posterior y se envió a la pila de navegación. Funcionó bien, pero algún tiempo después, en algunos casos, minutos (!) La aplicación se bloqueó. Gracias a la respuesta de Lou y su blog, pude obtener el EXC_BAD_ACCESS mucho más cerca de la llamada de textViewShouldBeginEditing. De forma similar a las intentos de desparate de Earler de moverse por EXC_BAD_ACCESS Comente el UITextView e invoque al controlador de vista para que se llame usando algún otro elemento de UIButton. (Solo una solución temporal rápida) Afortunadamente esto funcionó. La aplicación no se colgó más. Ahora iré por una implementación más sofisticada que traerá la misma experiencia de usuario pero llamará al otro controlador de vista de una manera diferente pero segura.

Proporciono esta respuesta en caso de que alguien más se encuentre con el mismo problema. Si tiene una explicación a mano sobre qué detalle causó exactamente el problema, entonces su impacto es muy apreciado.

Cuestiones relacionadas