Eh bien, ce que je fais habituellement, c'est que mes méthodes qui pourraient provoquer des erreurs au moment de l'exécution prennent une référence à un NSError
pointeur. Si quelque chose se passe vraiment mal dans cette méthode, je peux remplir la NSError
référence avec des données d'erreur et retourner nil à partir de la méthode.
Exemple:
- (id) endWorldHunger:(id)largeAmountsOfMonies error:(NSError**)error {
// begin feeding the world's children...
// it's all going well until....
if (ohNoImOutOfMonies) {
// sad, we can't solve world hunger, but we can let people know what went wrong!
// init dictionary to be used to populate error object
NSMutableDictionary* details = [NSMutableDictionary dictionary];
[details setValue:@"ran out of money" forKey:NSLocalizedDescriptionKey];
// populate the error object with the details
*error = [NSError errorWithDomain:@"world" code:200 userInfo:details];
// we couldn't feed the world's children...return nil..sniffle...sniffle
return nil;
}
// wohoo! We fed the world's children. The world is now in lots of debt. But who cares?
return YES;
}
Nous pouvons alors utiliser la méthode comme celle-ci. Ne vous embêtez même pas à inspecter l'objet d'erreur à moins que la méthode ne renvoie nil:
// initialize NSError object
NSError* error = nil;
// try to feed the world
id yayOrNay = [self endWorldHunger:smallAmountsOfMonies error:&error];
if (!yayOrNay) {
// inspect error
NSLog(@"%@", [error localizedDescription]);
}
// otherwise the world has been fed. Wow, your code must rock.
Nous avons pu accéder aux erreurs localizedDescription
car nous avons défini une valeur pour NSLocalizedDescriptionKey
.
Le meilleur endroit pour plus d'informations est la documentation d'Apple . C'est vraiment bien.
Il existe également un didacticiel simple et agréable sur Cocoa Is My Girlfriend .
id
à unBOOL
. Toute légère variation compatible ARC serait très appréciée.BOOL
. RetourNO
en cas d'erreur et au lieu de vérifier la valeur de retour, il suffit de vérifiererror
. Sinil
allez-y,!= nil
manipulez-le.**error
n'est pas nul. Sinon, le programme lancera une erreur qui est complètement hostile et ne rend pas évident ce qui se passe.Je voudrais ajouter quelques suggestions supplémentaires basées sur ma dernière mise en œuvre. J'ai regardé du code d'Apple et je pense que mon code se comporte de la même manière.
Les articles ci-dessus expliquent déjà comment créer des objets NSError et les renvoyer, donc je ne vais pas m'embêter avec cette partie. Je vais juste essayer de suggérer un bon moyen d'intégrer les erreurs (codes, messages) dans votre propre application.
Je recommande de créer 1 en-tête qui sera un aperçu de toutes les erreurs de votre domaine (ex: application, bibliothèque, etc.). Mon en-tête actuel ressemble à ceci:
FSError.h
FSError.m
Maintenant, lorsque vous utilisez les valeurs ci-dessus pour les erreurs, Apple crée un message d'erreur standard de base pour votre application. Une erreur pourrait être créée comme suit:
Le message d'erreur standard généré par Apple (
error.localizedDescription
) pour le code ci-dessus ressemblera à ceci:Error Domain=com.felis.myapp Code=1002 "The operation couldn’t be completed. (com.felis.myapp error 1002.)"
Ce qui précède est déjà très utile pour un développeur, car le message affiche le domaine où l'erreur s'est produite et le code d'erreur correspondant. Les utilisateurs finaux n'auront aucune idée de ce
1002
que signifie le code d'erreur , alors nous devons maintenant implémenter de beaux messages pour chaque code.Pour les messages d'erreur, nous devons garder à l'esprit la localisation (même si nous n'implémentons pas immédiatement les messages localisés). J'ai utilisé l'approche suivante dans mon projet actuel:
1) créez un
strings
fichier qui contiendra les erreurs. Les fichiers de chaînes sont facilement localisables. Le fichier pourrait ressembler à ceci:FSError.strings
2) Ajoutez des macros pour convertir les codes entiers en messages d'erreur localisés. J'ai utilisé 2 macros dans mon fichier Constants + Macros.h. J'inclus toujours ce fichier dans l'en-tête du préfixe (
MyApp-Prefix.pch
) pour plus de commodité.Constantes + Macros.h
3) Il est maintenant facile d'afficher un message d'erreur convivial basé sur un code d'erreur. Un exemple:
la source
Constants+Macros.h
et j'importe ce fichier dans l'en-tête de préfixe (.pch
fichier) afin qu'il soit disponible partout. Si vous voulez dire que vous n'utilisez qu'une des deux macros, cela pourrait fonctionner. Peut-être que la conversion deint
versNSString
n'est pas vraiment nécessaire, même si je n'ai pas testé cela..strings
fichier), car c'est là que la macro d'Apple se penchera. Lisez à propos de l'utilisationNSLocalizedStringFromTable
ici: developer.apple.com/library/mac/documentation/cocoa/conceptual/…FS_ERROR_LOCALIZED_DESCRIPTION
vérifie la chaîne localisable dans un fichier appeléFSError.strings
. Vous voudrez peut-être consulter le guide de localisation d'Apple sur les.strings
fichiers si cela vous est étranger.Excellente réponse Alex. Un problème potentiel est la déréférence NULL. Référence d'Apple sur la création et le retour d'objets NSError
la source
Objectif c
Swift 3
la source
Veuillez vous référer au tutoriel suivant
J'espère que cela vous sera utile, mais avant de lire la documentation de NSError
Ceci est un lien très intéressant que j'ai trouvé récemment ErrorHandling
la source
Je vais essayer de résumer la grande réponse d'Alex et le point de jlmendezbonini, en ajoutant une modification qui rendra tout compatible avec ARC (jusqu'à présent ce n'est pas puisque ARC se plaindra puisque vous devriez revenir
id
, ce qui signifie "n'importe quel objet", mais ceBOOL
n'est pas un objet type).Maintenant, au lieu de vérifier la valeur de retour de notre appel de méthode, nous vérifions si
error
c'est toujoursnil
. Si ce n'est pas le cas, nous avons un problème.la source
Un autre modèle de conception que j'ai vu implique l'utilisation de blocs, ce qui est particulièrement utile lorsqu'une méthode est exécutée de manière asynchrone.
Supposons que nous ayons défini les codes d'erreur suivants:
Vous définiriez votre méthode qui peut générer une erreur comme ceci:
Et puis, lorsque vous l'appelez, vous n'avez pas à vous soucier de déclarer l'objet NSError (l'achèvement du code le fera pour vous) ou de vérifier la valeur renvoyée. Vous pouvez simplement fournir deux blocs: un qui sera appelé lorsqu'il y aura une exception et un qui sera appelé quand il réussira:
la source
Eh bien, c'est un peu hors de portée, mais si vous n'avez pas d'option pour NSError, vous pouvez toujours afficher l'erreur de bas niveau:
la source
que je peux utiliser
NSError.defaultError()
chaque fois que je n'ai pas d'objet d'erreur valide.la source