He utilizado el manejo de excepciones para mi bastante intensivo audio app sin ningún tipo de problema. Después de mucha lectura y un poco de análisis de evaluación comparativa y desensamblaje, llegué a la controvertida conclusión de que no hay una razón real para no usarlos (inteligentemente) y muchas razones para no hacerlo (punteros punteros NSError, interminables condicionales ... ¡puaj!). La mayoría de lo que dice la gente en los foros es simplemente repetir los Apple Docs.
de entrar en un poco de detalle en this blog post 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 atrapar 1 millón de excepciones toma aproximadamente 8.5 segundos. Esto equivale a solo 8,5 microsegundos para cada uno. ¿Caro en su hilo de CoreAudio en tiempo real? Tal vez un poco (pero nunca arrojarías excepciones, ¿verdad?), Pero un retraso de 8,5 μs en el UIAlert diciéndole al usuario que hubo un problema al abrir su archivo, ¿se va a notar?
Mito 2: Bloques @try tienen un costo de 32 bits En iOS
Los documentos de Apple hablan de "bloques @try de costo cero en 64 bits" y afirman que 32 bits incurre en un costo. Un pequeño análisis de benchmarking y desensamblaje parece indicar que hay bloques @try de costo cero en iOS de 32 bits (procesador ARM) también. ¿Apple quiere decir 32bit Intel?
Mito 3: importa que las excepciones lanzado a través de cacao Los marcos son Indefinido
sí, son "indefinido", pero ¿qué haces tirar a través del marco de Apple de todos modos? Por supuesto Apple no los maneja por usted. El objetivo de implementar el manejo de excepciones para errores recuperables es manejarlos localmente, pero no cada línea individual "localmente".
Un caso de borde aquí es con métodos como NSObject:performSelectorOnMainThread:waitUntilDone:
. Si el último parámetro es SÍ, esto actúa como una función síncrona, en cuyo caso se le puede perdonar que espere que la excepción suba al alcance de su llamada. 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 solucionar este problema fácilmente usando el GCD dispatch_synch
y poniendo en su argumento de bloque la llamada al método más cualquier manejo de excepción.
¿Por qué utilizar NSException de más de
Cualquiera de NSError que alguna vez ha hecho 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 beneficio principal @ try/@ catch y NSExceptions es hacer que su código sea más limpio y fácil de mantener.
Supongamos que tiene 5 líneas de código que funcionan en un archivo. Cada uno podría arrojar uno de, por ejemplo, 3 errores diferentes (por ejemplo, espacio en disco, error de lectura, etc.). En lugar de envolver cada línea en un condicional que busca un valor de retorno NO y luego subcontrata la investigación del puntero NSError a otro método ObjC (o peor, utiliza una macro #define
), ajusta las 5 líneas en una sola @try y manejar cada error allí mismo. ¡Piensa en las líneas que ahorrarás!
Al crear subclases de NSException, también puede centralizar fácilmente los mensajes de error y evitar tener su código lleno de ellos. También puede distinguir fácilmente las excepciones "no fatales" de su aplicación de los errores fatales del programador (como NSAssert). También puede evitar la necesidad de la constante "nombre" (el nombre de la subclase, es el "nombre").
ejemplos de todo esto y más detalles acerca de los puntos de referencia y desmontaje son on this blog post ...
excepciones más try/catch/finally es el paradigma utilizado por casi todos los otros idiomas principales (C++, Java, PHP, Ruby, Python). Tal vez es hora de abandonar la paranoia y abrazarla también ... al menos en iOS.
¿Puede explicar que el "Comportamiento de cualquier excepción arrojada a través del código del sistema no está definido". ¿en detalle? – Krishnan
Se actualizó la pregunta .... – Krishnan
+1, es agradable. ¿Puede decirme por favor que mi suposición con respecto a la excepción no es correcta? Si utilizo NSException en caso de Excepción particular (suponga que Matriz está fuera de límite) .luego se carga todas las clases para verificar la excepción. Responda. – Ishu