Pregunta

Soy un largo tiempo de desarrolladores de Microsoft y yo soy nuevo en el desarrollo del iPhone usando Xcode. Por lo tanto, estoy leyendo un libro y pasando por ejemplos tratar de enseñar a mí mismo cómo escribir una aplicación para iPhone con Objective-C. Todo ha sido bueno hasta ahora, sin embargo, de vez en cuando me encuentro con el mensaje genérico 'objc_exception_throw' en tiempo de ejecución. Cuando esto sucede, la fuente de esta excepción es muy difícil de encontrar. Después de algún ensayo y error que encontré mi respuesta. Uno de los parámetros con errores de ortografía.

Como se puede ver a continuación, lo escribo mal el parámetro '' otherButtonTitles dejando fuera la segunda 't' en el botón.

UIAlertView *alert = [[UIAlertView alloc] 
                      initWithTitle:@"Date and Time Selected" 
                      message:message 
                      delegate:nil
                      cancelButtonTitle:@"Cancel"
                      otherButonTitles:nil];

La razón de que esto me llevó tiempo para encontrar es que el código construido con éxito. ¿Es este comportamiento normal para el compilador de Objective-C? Estoy acostumbrado a tener la acumulación fracasan en el compilador .NET cuando hago un error de sintaxis común como este. ¿Hay un ajuste compilador puedo cambiar para que el construido fallar cuando hago estos errores?

¿Fue útil?

Solución

En primer lugar, ~/.gdbinit abierta (que es el archivo llamado .gdbinit en su directorio personal - sí, comienza con un punto) y poner esto en él:

fb -[NSException raise]
fb objc_exception_throw
fb malloc_error_break

Eso va a inicializar el BGF con tres puntos de ruptura predeterminada, cuando se producen, BGF detener su solicitud y le mostrará el seguimiento de la pila. Esto está muy bien integrado con Xcode por lo que será capaz de caminar bien a través de su código haciendo clic en los elementos traza de la pila tan pronto como se produce en alguna parte una excepción o una falla malloc.

A continuación, abra el panel Get Info en su proyecto (o seleccione su proyecto (arriba elemento de la Groups & Files) y pulsa cmd-i), vaya a la pestaña Build y establecer Base SDK de su proyecto para Device - iPhone OS [someversion]. Desplazarse todo el camino hasta el fondo y encontrar la sección GCC 4.0 - Warnings. Ahí; encender tantas advertencias a medida que se sienta cómodo, pero asegúrese de encender Treat Warnings as Errors (esto es el equivalente a GCC_TREAT_WARNINGS_AS_ERRORS). En lo personal, yo tengo configurado a esto:

Advertencia GCC la configuración de creación
(fuente: lyndir.com )

Ahora debería estar recibiendo advertencias del compilador para la mayoría de las cosas que puede hacer mal en el código y el compilador no permite ejecutar el código hasta que a solucionarlos. Cuando las cosas consiguen más allá de la nariz del compilador, debe ser capaz de encontrar el problema fácilmente con el BGF rompiendo en un lugar conveniente.

También debe buscar en NSZombie*. Estas son las variables de entorno que son muy útiles para la ruptura temprana de malas situaciones de asignación de memoria o de acceso. Por ejemplo; wih NSZombieEnabled nada realmente va a ser puesto en libertad; en dealloc que va a llegar sobrescribe con _NSZombie y debe intentar acceder a esta memoria dealloced de nuevo (eliminación de referencias a un puntero dealloced) que obtendrá algo para romper el BGF en lugar de la llamada pasando por como normal, sólo se publica en al azar datos (que, por supuesto, no es lo deseado). Para obtener más información al respecto, consulte http://www.cocoadev.com/index.pl?NSZombieEnabled .

Otros consejos

Siempre use el ajuste -Werror GCC (GCC_TREAT_WARNINGS_AS_ERRORS = YES). Nunca se debe tener advertencias en el código y este es un ejemplo en el que la advertencia es un error crítico.

Además, si se obtiene una objc_exception_throw, cambiar a la consola (Comando + Mayúsculas + R) y buscar la primera dirección de número "bajo".

2009-04-01 13:25:43.385 CrashExample[41720:20b] Stack: (
    2528013804,
    2478503148,
    2528036920,
    2528053460,
    2358032430,
    11076,
    11880,
    816174880,
    345098340,
    145973440,
    816174880,
)

En este caso sería "11076". Así que escribir en la consola:

info line *11076

Que le dirá la línea en su código, donde se lanzó la excepción.

parámetros mal escritas redundan generalmente en una "Advertencia: tal y como objeto no responden al selector x" en amarillo en la línea en cuestión. Creo que esto está activada por defecto, ya que no tiene que cambiar ninguna configuración del compilador para ver estos.

Además, cuando me encuentro con una excepción no capturada, a veces es beneficioso para caer en la consola GDB (debería aparecer cuando se ejecuta la aplicación) y escriba lo siguiente para obtener trazas de todas las discusiones:

t a a bt

Lo que hiciste no es un error en tiempo de compilación, porque los controles de tiempo de ejecución de Objective-C en tiempo de ejecución si un objeto puede responder al mensaje que envíe a la misma.

Recomiendo añadir esta opción a su objetivo o proyecto de construcción:

GCC_TREAT_WARNINGS_AS_ERRORS = YES

La razón por la que no es un error de compilación, se debe a que es perfectamente válida para enviar un mensaje no se conoce en tiempo de compilación a cualquier objeto (y cualquier objeto puede ser configurado para manejar mensajes de forma dinámica también). Todas las llamadas a métodos son realmente los mensajes que se envían a los objetos.

En general, si hay advertencias que debe hacer frente a las mismas, como en la mayoría de los casos pueden conducir a problemas (como se vio). El aspecto es engañosa aquí es que si se compila un archivo una vez y tiene sólo advertencias, si compila otras clases sin realizar cambios en la clase que tiene advertencias, la advertencia no se mostrará en los mensajes del compilador. Así que de vez en cuando es posible que desee "limpiar" todos los objetivos y construir de nuevo para asegurarse de que no falte a ninguna de las advertencias.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top