2010-10-18 10 views
1

Je (comme certains d'entre vous le savent d'après mes autres questions :)) je construis une bibliothèque statique cacao-touch, et j'ai le code [NSException raise:@"This is the name of my exception" format:@"This is my format", nil] dispersé dans mon projet comme un raccourci vers la sous-classe NSException . Cela revient à me mordre, car je dois attraper SEULEMENT une exception qui a une certaine chaîne dans le nom, et laisser les autres passer.Objective-C catch spécifique type d'exception

Maintenant, je sais que si je pouvais, je NSException sous-classé faire:

@try { 
    NSLog(@"This is some code that might raise an exception"); 
} 
@catch (MyException *e){ 
    NSLog(@"Yep, something went wrong....%@", e); 
} 
@finally { 
    NSLog(@"This is my cleanup code"); 
} 

Mais est-il un moyen plus facile de me faire ce que refactorisation tout mon code?

Répondre

3

No - sous-classe NSException si vous souhaitez différents types d'exceptions.

Toutefois, les exceptions ne doivent pas être utilisées pour le flux de contrôle sur iOS. Les exceptions ne doivent être utilisées que pour les erreurs non récupérables. N'utilisez pas d'exceptions pour, disons, la validation de l'entrée de l'utilisateur.


Pourquoi vous ne devez pas utiliser d'exceptions; les frameworks sont explicitement conçus et implémentés de manière à ce que les exceptions ne soient utilisées que pour indiquer des erreurs irrécupérables. Toute exception renvoyée par le code dans les frameworks - jetés sur une trame de pile qui est dans les frameworks - aura un comportement indéfini. Vous ne pouvez pas "réparer" cela en nettoyant la mémoire de votre portée locale dans @finally (pas plus que vous ne pouvez rendre threadsafe de code non threadsafe en "appliquant suffisamment de verrous").

Pour les erreurs irrécupérables, allez-y et lancez NSExceptions, signalez l'erreur et plantez. Cependant, sachez qu'il vaut mieux appeler abort() au moment où le problème est détecté pour que le crash contienne la pile complète.

Pour les erreurs récupérables, utilisez NSError dans le même modèle que le reste des cadres.

+0

Ok darnit, cela signifiera probablement passer des nuits blanches (148 occurrences, Aïe! :)) mais non, ce sont des erreurs majeures comme indices non valides, la corruption de fichiers, schémas verrouillés, etc. –

+0

Pourquoi les exceptions ne devraient-elles pas être utilisées pour le traitement des erreurs "normales"? –

+1

@Tilo parce que la mémoire est souvent fuite par eux car ils contournent toute gestion manuelle que vous ou Apple faites. – cobbal

1

Le NSException ne classe-t-il pas un accesseur pour lire la chaîne que vous voulez faire correspondre? Ensuite, vous pouvez écrire

@try { 
    … 
} @catch (NSException *e) { 
    if ([[e …] isEqual: @"…"]) { 
     … 
    } else { 
     @throw e; 
    } 
} 
+0

Oui, l'accesseur est -name. –