2011-05-10 15 views
5

Tengo una pregunta sobre el manejo de errores/excepciones en el iPhone.Cómo manejar correctamente los errores en el iPhone

He leído la documentación sobre Excepción, y parece que las excepciones se pueden usar solo para situaciones excepcionales.

¿Significa que no puede usarlos como en java?

por ejemplo, estoy tratando de escribir un controlador de caso de uso para mi aplicación. Tengo algunos ejemplos en Java de proyectos anteriores en ese idioma, que usan excepciones en caso de errores.

la pregunta simplemente es: ¿puedo seguir el ejemplo que tengo en Java, y "traducirlo" en Objective-C (y usar excepciones de Objective-C) o hay una mejor manera de hacerlo?

Este es el código me gustaría hacer Objective-C amigable:

public void addPerformance(Perfomance perf) { 
     //do some preparation 
      ... 
    //execute the usecase 
     executor(new AddPerformance(perf)); 
} 

    private void executor(Usecase usecase) { 

      try { 
       UnitOfWorkServices.INSTANCE.bizTransactionStart(); 
       usecase.execute(); 
UnitOfWorkServices.INSTANCE.bizTransactionCommit(); 
      } catch (RealException re) { 
       UnitOfWorkServices.INSTANCE.bizTransactionEscape(); 
       throw re; 
      } catch (Exception e) { 
       UnitOfWorkServices.INSTANCE.bizTransactionEscape(); 
       throw new FatalException(this.getClass().getName() + "/executor(" 
         + usecase.getClass().getSimpleName() + ")", e, 
         "APPXCP_006_UNEXPECTED_EXCEPTION", 
         "\n\t |*| : Unexpected exception translated into FatalException"); 
      } finally { 
       UnitOfWorkServices.INSTANCE.bizTransactionEnd(); 
      } 
     } 

Todas las excepciones están destinados a ser capturado por la interfaz de usuario para mostrar un mensaje de error.

gracias por su ayuda, Michael

Respuesta

3

En general, sí, se puede traducir su lógica try/catch en una construcción comparable en Objective-C y obtener resultados comparables. Aunque tenga cuidado con esa línea throw re;, ya que una excepción no detectada en el iPhone bloqueará su aplicación.

Más al punto, sin embargo, el patrón estándar utilizado por el iPhone SDK y otras bibliotecas de uso común es que en lugar de arrojar excepciones, los métodos API que pueden fallar por una variedad de razones devuelven un valor booleano que indica si la operación fue exitoso, y acepta como parámetro una referencia a un puntero NSError que se utiliza en caso de error para proporcionar al llamante detalles específicos sobre lo que salió mal. Así pues, en este caso, el código podría traducir a algo más parecido a:

NSError* error = nil; 
[[UnitOfWorkServices sharedInstance] bizTransactionStart]; 
bool success = [usecase execute:&error]; 
if (success) { 
    [[UnitOfWorkServices sharedInstance] bizTransactionCommit]; 
} 
else if (error) { 
    int code = [error code]; 
    [[UnitOfWorkServices sharedInstance] bizTransactionEscape]; 
    if (code == MY_MINOR_ERROR_CODE) { 
     //do something 
    } 
    else if (code == MY_FATAL_ERROR_CODE) { 
     //do something else 
    } 
    else { 
     //handle unexpected error type(s) 
    } 
} 
else { 
    //operation failed with no specific error details 
    [[UnitOfWorkServices sharedInstance] bizTransactionEscape]; 
    //handle generic error 
} 
[[UnitOfWorkServices sharedInstance] bizTransactionEnd]; 
+0

genial! Muchas gracias por su respuesta ! – Themikebe

+0

Solo una pequeña cosa, si se llama al código anterior desde una instancia compartida (el controlador de casos de uso) que se llama desde la interfaz de usuario, ¿funciona de la misma manera? error 'NSError *; [[UCCServices sharedInstance] addPerformance: perf andError: & error]; if (error) {// alerta de dislay con información de error} ' – Themikebe

+2

Esta respuesta es incorrecta en dos detalles importantes; ** no puedes ** traducir el código pesado de excepción al Objective-C y esperar obtener el mismo comportamiento ** a menos que ** ese código no llame a los frameworks * del sistema * en absoluto *. En segundo lugar, 'if (error)' es * siempre incorrecto *; una vez que haya comprobado que 'success' es falso, se debe establecer' error' * * (si no está configurado, ha encontrado un error en el código que ha llamado). – bbum

1

Puede utilizar las excepciones del mismo modo que utilizar las excepciones en Java, pero no es la forma Recomendado para hacerlo. Traducir Java a Objective-C de esa manera funciona, y la mayoría de las personas entenderán tus intenciones. Pero el resultado será tan malo como si intentara traducir inglés a alemán utilizando un diccionario; la ortografía es perfecta, pero la gramática y el contexto están completamente equivocados.

Comprender la "manera Cocoa" para manejar errores y excepciones lo ayudará a crear aplicaciones iOS más robustas, y le dará una mejor comprensión de cómo usar la API oficial y de terceros.

he escrito un post más largo blog sobre el tema aquí: http://blog.jayway.com/2010/10/13/exceptions-and-errors-on-ios/

Permite recapitular las partes importantes:

excepciones sólo se debe utilizar para los errores de programación, y cosas por el fatal que no se puede recuperar. Por ejemplo, excepción fuera de límites, si llamó con el argumento equivocado la primera vez que su aplicación tiene un error, volver a intentar 100 veces no arreglará su aplicación, solo seguirá fallando. Las excepciones son excepciones al flujo de trabajo normal y para ayudarlo a solucionar todos los errores antes de envíe la aplicación a los usuarios finales.

NSError instancias es lo que utiliza para los errores causados ​​por los usuarios y cosas de las que su aplicación puede recuperarse. Por ejemplo, errores IO, el usuario puede querer volver a conectarse a la red, probar una nueva contraseña e intentar nuevamente. Esto se debe a los errores que puede predecir, y que la aplicación o el usuario pueden hacer algo al respecto.

+0

¡Gracias por tu respuesta! – Themikebe

+2

Nuevamente; no puede traducir el código de excepciones pesadas a Objective-C, conservando las excepciones, y que funcione correctamente si hay llamadas a través de los marcos. En Cocoa/iOS, las excepciones arrojadas sobre los marcos de la pila de marcos son, por definición, un comportamiento indefinido. Por lo general, parece funcionar, pero eso es solo una coincidencia y puede cambiar en el futuro. – bbum

+0

Pero, ¿cuándo querría @catch un error de programación fatal? A mí me parece extraño que Apple haya agregado esta construcción a Objective-C y, sin embargo, aliente a todos a alejarse de ella. –

Cuestiones relacionadas