2009-10-01 14 views
10

¿Soy nuevo en Object-c y estoy comenzando a preguntarme cuál es la forma común/estándar/adecuada para manejar y detectar errores?Devolución de errores en el objetivo-c

Parece que es posible usar NSError para hacer esto, ¿es una buena idea o un secuestro de cocoa?

Respuesta

17

Estoy bastante seguro de que eso es lo que hace la clase NSError: dar detalles sobre los errores. El patrón más común que verá es un método que toma un puntero a un objeto NSError, como en:

- (id)doSomethingWithArgument:(id)arg error:(NSError **)error

El método devuelve un valor (o posiblemente nil) para el resultado de hacer algo, pero si el la llamada fallida colocará un objeto NSError en el puntero pasado con detalles sobre la falla. Su documentación es responsable de especificar qué se devuelve si el método encuentra un error.

El otro método que me viene a la mente es el @throw - @catch bloque; sin embargo, en Objective-C @throw, una excepción puede ser bastante costosa desde el punto de vista computacional y, por lo general, solo se recomienda hacerlo en situaciones verdaderamente excepcionales.

Editar: wow, resulta que mucha gente tiene opiniones muy fuertes sobre @throw excepciones. Para resumir el comentario (muy útil) sobre el tema:

  • excepciones que lanzan más a menudo deben hacer frente a error del programador (situaciones que deben Nunca suceder, y similares); las excepciones no deben usarse para el manejo de errores ordinarios. En su lugar, utilice el método error que se muestra arriba o publique instancias de NSNotification.
  • Si terminas haciendo un uso extensivo de los bloques @throw/@catch, ten mucho cuidado con la lógica que los rodea. Objective-C proporciona muchas maneras de separar los métodos para ejecutarlos en otros hilos, o retrasar la ejecución, etc. Tenga mucho cuidado de tener en cuenta todas esas posibilidades cuando escribe su código.

Por último, otro punto muy válido:

  • Si usted hace uso del objeto error pasado a un método, el valor de retorno debe indicarlo. No intente hacer ambas cosas (devuelva un objeto parcialmente válido y configure el objeto error).
+2

Intentar @throw algo que quedará atrapado fuera de su alcance también tiene muchos problemas lógicos sutiles en ObjC. ¿Qué sucede si un NSTimer te llama por ejemplo? ¿Quién va a atrapar la excepción (y evitar chocar)? Las excepciones de ObjC simplemente no son lo suficientemente potentes como para manejar modismos de ObjC comunes. Por lo general, solo son útiles para resolver los errores de programación. NSError es definitivamente el camino correcto si necesita un objeto de error rico para uso general. –

+2

Para aclarar, las "situaciones verdaderamente excepcionales" en Cocoa casi siempre son un error del programador, y por lo general son irrecuperables, o al menos fácilmente evitables con los controles adecuados y necesarios. Lanzar una excepción solo para señalar algo al programador no es una buena práctica en Objective-C, y hoy en día incluso se desaconseja en Java, no por el costo computacional sino porque aumenta en gran medida la complejidad del código del cliente. –

+4

Continuando con este concepto, incluso la idea del manejo centralizado de errores tiene mejores implementaciones que las excepciones en Cocoa. A menudo arrojo un error en NSNotifications que son observados por algún objeto central de manejo de errores para proporcionar comentarios del usuario. Cuando se combina con la lógica de reintentos de encapsulado de NSError, esto puede hacer que "publicar una notificación y regresar" sea una solución muy efectiva para los errores que impactan al usuario. –

Cuestiones relacionadas