iphone objective-c ios c xcode

iphone - Registre UncaughtExceptionHandler en Objective C usando NSSetUncaughtExceptionHandler



objective-c ios (3)

Mi código para registrar manejador de excepciones no detectadas usando UncaughtExceptionHandler es el siguiente, ¿cree que habrá algún problema potencial?

@interface AppDelegate () void myHandler(NSException * exception); @end @implementation AppDelegate void myHandler(NSException * exception) { // ... } - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSSetUncaughtExceptionHandler(&myHandler); ..

¿Es posible tener una forma más concisa de escribirlo?

Necesito usar la extensión de clase para declarar el prototipo para deshacerme de la advertencia de No hay prototipo previo para la función.


La respuesta de Martin es correcta. Sin embargo, pensé que elaboraría un poco, para explicar por qué es así.

La definición de tu función:

void myHandler(NSException * exception) { // ... }

define una función que será visible externamente. En otras palabras (generalizadas, no técnicas), se creará un símbolo en el archivo objeto para que el vinculador pueda encontrarlo, lo que permite que otros archivos llamen a myHandler .

Sin embargo, como se supone que es visible externamente, otros archivos tendrán que saber cómo se ve esa función. Ahí es donde el prototipo entra en juego. La advertencia es básicamente decir ...

Oye, has declarado que esta función es externamente visible para otros códigos, pero no veo un prototipo que otro código pueda usar para conocer la función.

Entonces, recibes una advertencia. Es una buena advertencia para tener. Le ayuda a recordar declarar prototipos para las funciones que desea exportar.

Ahora, como descubriste, puedes declarar un prototipo y la advertencia desaparece. Sin embargo, declarar el prototipo solo en el archivo de implementación debería ser otra advertencia para usted. Esa advertencia personal debería ser:

¿Realmente desea que esta función tenga visibilidad externa o solo se llama en esta unidad de compilación? Si la función no va a tener visibilidad externa, entonces no hay necesidad de exportarla en la tabla de símbolos, y no hay necesidad de un prototipo que otros módulos puedan incluir para que conozcan la función.

En ese caso, puede declarar la función static como en la respuesta de Martin:

static void myHandler(NSException * exception) { // ... }

En este contexto, static le dice al compilador algo como:

Oye, compilador, crea código para esta función y permite que cualquier código en esta unidad de compilación vea la función, pero no le otorgas visibilidad externa. No deseo que la función sea llamada por otros módulos.

En este caso, incluso si otro código declarara el prototipo, no verían su función porque es "privada" para el archivo en el que está definida.

Dado que se está utilizando solo en el archivo local, no es necesario un prototipo, por lo que no es necesario advertirle que no tiene uno.

Ahora, solo como una nota ... No necesita poner funciones C en las secciones @interface y @implementation de su código, ya que eso no hace nada. Esas funciones C se compilan con la misma visibilidad y acceso exactos, ya sea que estén dentro de las secciones ObjC o no.

Finalmente, si lo desea, puede desactivar esta advertencia en la configuración de compilación de Xcode (pero ahora que comprende el contexto de la advertencia, le sugiero que la deje activada).


No recibe una advertencia sobre un prototipo perdido si declara la función como static :

static void myHandler(NSException * exception) { // ... }


Sí, esta es la forma correcta. Me pregunto por qué recibes la advertencia porque tengo lo mismo sin declararlo en una categoría vacía y no aparece una advertencia ... Además, también puedes configurar manejadores de señal para detectar las señales SIGABRT , SIGILL y SIGBUS :

void signalHandler(int sig) { } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { struct sigaction newSignalAction; memset(&newSignalAction, 0, sizeof(newSignalAction)); newSignalAction.sa_handler = &signalHandler; sigaction(SIGABRT, &newSignalAction, NULL); sigaction(SIGILL, &newSignalAction, NULL); sigaction(SIGBUS, &newSignalAction, NULL); ... }