Pregunta

Uno de mis amigos me pidió que no usara NSException en iPhone Apps. La razón que dio fue "cuello de botella". Pero no estoy convencido de ello.

Puede alguien confirmar que deberíamos restringir el uso de NSException en iPhone App? Si usted tiene las mejores prácticas para el uso de NSException, debe facilitarse también.

ACTUALIZACIÓN:

Este Enlace nos pide que utilice Tratamiento de excepciones en el nivel de aplicación. Haga que alguien ha hecho alguna vez? Por favor, dar las ventajas de la misma y cualquier otra actuación tirones que podría crear.

¿Fue útil?

Solución

En resumen:

No utilice excepciones para indicar cualquier cosa, pero no recuperables errores

Esto sólo es adecuado para su uso @ try / @ captura para hacer frente a errores irrecuperables. Nunca es apropiado usar @ tirar / @ try / @ captura para hacer control de flujo de operaciones similares en iOS o Mac OS X. Incluso entonces, considerar cuidadosamente si usted es mejor usar una excepción para indicar un error irrecuperable o simplemente estrellarse ( llamar abort ()); Un choque a menudo deja detrás significativamente más pruebas.

Por ejemplo, no sería apropiado utilizar para la captura fuera de los límites excepciones a menos que su objetivo es atraparlos y de alguna manera informar del error, entonces - por lo general - accidente o, al menos, advertir al usuario que su aplicación está en un estado incoherente y puede perder datos.

Comportamiento de cualquier excepción lanzada a través de código de la arquitectura del sistema no está definido.


  

Puede explicar el "comportamiento de cualquier   excepción lanzada a través del sistema   código de la arquitectura no está definido." En   detalle?

Claro.

Los marcos de sistemas usan un diseño en el que se considera cualquier excepción a ser un fatal, no recuperable, error; un error del programador, para todos los efectos. Hay un número muy limitado de excepciones (je) a esta regla.

Por lo tanto, en su aplicación, los marcos sistema no asegurarse de que todo está necesariamente adecuadamente limpiado si una excepción es lanzada que pasa por código de la arquitectura del sistema. Sine excepción es, por definición, irrecuperable, ¿por qué pagar el costo de la limpieza?

Considere esta pila de llamadas:

your-code-1()
    system-code()
        your-code-2()

es decir. código donde sus llamadas código en el código del sistema que pone en más de su código (un patrón muy común, aunque las pilas de llamadas son obviamente significativamente más profundo).

Si your-code-2 produce una excepción, que las excepciones pasa sobre system-code significa el comportamiento es indefinido; system-code puede o no puede salir de su aplicación en un indefinido, potencialmente crashy o datos con pérdidas, estado.

O, con mayor intensidad:. No se puede lanzar una excepción en your-code-2 con la expectativa de que se puede capturar y manejar en your-code-1

Otros consejos

He usado el manejo de excepciones para mi bastante intensiva aplicación de audio sin ningún problema. Después de mucho leer y un poco de la evaluación comparativa y el desmontaje de análisis, he llegó a la controvertida conclusión de que no hay una verdadera razón para no usarlos (inteligente) y un montón de razones para no NSError (puntero triples, un sinfín de condicionales ... puaj!). La mayor parte de lo que se dice en los foros es simplemente repetir la Manzana Docs.

entro en un poco de detalle en esta entrada de blog pero voy a esbozar mis resultados aquí:

Mito 1: @ try / @ captura / @ finalmente es demasiado costoso (en términos de CPU)

En mi iPhone 4, lanzar y recoger 1 millón de excepciones tarda unos 8,5 segundos. Esto equivale a alrededor de sólo 8,5 microsegundos para cada uno. Costosa en tiempo real en su CoreAudio hilo? Tal vez un poco (pero que nunca había lanzar excepciones allí ¿verdad ??), pero un retraso en la 8.5µs UIAlert que indica al usuario que hay un problema al abrir su archivo, es que va a ser notado?

Mito 2: @try bloques tienen un costo a 32 bits IOS

Los documentos de Apple hablan de "bloques de costo cero @try en de 64 bits " y afirma que 32 bits incurre en un costo. Un poco de la evaluación comparativa y desmontaje análisis parece indicar que no hay bloques @try de costo cero en IOS de 32 bits (procesador ARM) también. Qué Apple quiere decir 32 bits Intel

Mito 3: importa que las excepciones lanzado a través de cacao Frameworks son Indefinido

Sí, son "indefinido", pero ¿qué haces tirar a través del marco de Apple de todos modos? Por supuesto Apple no maneja para usted. El objetivo de la implementación de la gestión de excepciones de errores recuperables es manejar de manera local -. Simplemente no todos de una sola línea "localmente"

Uno de los casos ventaja aquí es con métodos como NSObject:performSelectorOnMainThread:waitUntilDone:. Si el parámetro más adelante es SÍ, esto actúa como una función sincrónica en cuyo caso podría ser perdonado para contar con la excepción de la burbuja hasta que su ámbito de llamadas. Por ejemplo:

/////////////////////////////////////////////////////////////////////////
#pragma mark - l5CCThread
/////////////////////////////////////////////////////////////////////////

@interface l5CCThread : NSThread @end

@implementation l5CCThread

- (void)main
{
    @try {

        [self performSelectorOnMainThread:@selector(_throwsAnException) withObject:nil waitUntilDone:YES];

    } @catch (NSException *e) {
        NSLog(@"Exception caught!");
    }
}
- (void)_throwsAnException { @throw [NSException exceptionWithName:@"Exception" reason:@"" userInfo:nil]; }

@end

/////////////////////////////////////////////////////////////////////////
#pragma mark - l5CCAppDelegate
/////////////////////////////////////////////////////////////////////////

@implementation l5CCAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    l5CCThread *thd = [[l5CCThread alloc] init];
    [thd start];

    return YES;
}
// ...

En este caso la excepción pasaría "a través del marco de cacao" (bucle de ejecución del hilo principal) falta de su captura y estrellarse. Puede trabajar fácilmente alrededor de este uso de dispatch_synch de GCD y poniendo en él es argumento bloque de la llamada al método más cualquier tratamiento de excepciones.

¿Por qué utilizar NSException ha terminado de NSError

Cualquiera que haya hecho el trabajo en uno de los marcos más antiguas basadas-C como Core Audio sabe lo que es una tarea que está comprobando, la manipulación y notificación de errores. El principal beneficio @ try / @ captura y NSExceptions ofrece es hacer que su código más limpio y más fácil de mantener.

Supongamos que tiene 5 líneas de código que trabajan en un archivo. Cada uno podría tirar de, digamos, 3 errores diferentes (por ejemplo, sin espacio de disco, error de lectura, etc.). En lugar de envolver cada línea en una condicional que cheques por un valor de retorno NO y luego subcontrata la investigación puntero NSError a otro método ObjC (o peor, utiliza una macro #define!), Que se coloca todas las 5 líneas en un solo @try y manejar cada error allí mismo. Piense en las líneas que se ahorrará!

Al crear subclases NSException, puede fácilmente mensajes de error también centralizar, y evitar tener su código lleno de ellos. También puede distinguir fácilmente excepciones "no fatales" de tu aplicación de los errores fatales programador (como NSAssert). También puede evitar la necesidad de la constante "name" (nombre de la subclase, es el "nombre").

Los ejemplos de todo esto y más detalles acerca de los puntos de referencia y desmontaje son en esta entrada del blog ...

Las excepciones más try / catch / finally esel paradigma utilizado por casi todos los otros idiomas principales (C ++, Java, PHP, Ruby, Python). Tal vez es hora de dejar caer la paranoia y la abrazan, así ... al menos en IOS.

En general preguntarse si usted está tratando de señalar un error, o es lo que realmente tiene una condición excepcional? En el primer caso, entonces es una muy mala idea, independientemente de cualquier problema de rendimiento, real o percibida. En este último caso, es sin duda lo que hay que hacer.

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