web-dev-qa-db-fra.com

Objectif-C: assertion vs exception vs erreur

Dans Cocoa, quand dois-je utiliser NSAssert, NSException, NSError?

Voici ce que j'ai pensé:

NSAssert - Lors de la création d'un programme client utilisé pour le propre bénéfice des programmeurs afin de revérifier les règles, conventions, hypothèses ou pré-conditions et post-conditions?

NSException - Lors de la création d'une bibliothèque tierce au profit d'autres programmeurs qui utilisent la bibliothèque, afin qu'ils sachent immédiatement quand une entrée n'est pas valide?

NSError - Lors de l'interfaçage avec un système externe pour obtenir des données comme un fichier, une base de données ou un service Web qui ne garantissent pas de me donner un résultat?

79
Tobias

Un NSAssert lèvera une exception en cas d'échec. NSAssert est donc là pour être un moyen court et facile d'écrire et de vérifier toutes les hypothèses que vous avez faites dans votre code. Ce n'est pas (à mon avis) une alternative aux exceptions, juste un raccourci. Si une assertion échoue, quelque chose a terriblement mal tourné dans votre code et le programme ne devrait pas continuer.

Une chose à noter est que NSAssert ne sera pas compilé dans votre code dans une version, donc cela est généralement utilisé pour la vérification d'intégrité pendant le développement. En fait, j'ai tendance à utiliser une macro d'assertion personnalisée qui est toujours active.

Les fois où vous feriez @throw votre propre NSException est quand vous le voulez vraiment dans une version, et dans des choses comme les bibliothèques publiques/interface lorsque certains arguments ne sont pas valides ou que vous avez été appelé incorrectement. Notez qu'il n'est pas vraiment courant de @catch une exception et continuez d'exécuter votre application. Si vous essayez cela avec certaines des bibliothèques standard d'Apple (par exemple Core Data), de mauvaises choses peuvent se produire. Semblable à une assertion, si une exception est levée, l'application doit généralement se terminer assez rapidement car cela signifie qu'il y a une erreur de programmation quelque part.

NSErrors doit être utilisé dans vos bibliothèques/interfaces pour les erreurs qui ne sont pas des erreurs de programmation et qui peuvent être récupérées. Vous pouvez fournir des informations/codes d'erreur à l'appelant et ils peuvent gérer l'erreur proprement, alerter l'utilisateur le cas échéant et poursuivre l'exécution. Ce serait généralement pour des choses comme une erreur de fichier introuvable ou une autre erreur non fatale.

100
Mike Weller

La convention dans Cocoa est qu'une exception indique une erreur de programmation. Beaucoup de code, y compris le code du framework, n'est pas conçu pour fonctionner correctement après qu'une exception est levée.

Tout type d'erreur qui devrait être récupérable est représenté par un NSError. Il existe également un système pour présenter NSErrors à l'utilisateur. Comme vous le dites, cela est surtout utile pour les ressources externes faillibles.

Conceptuellement, une assertion est une déclaration qu'un prédicat donné évalue toujours à vrai; sinon, le programme est interrompu. Bien que son comportement puisse être modifié, la famille NSAssert est par défaut un moyen pratique de lancer NSInternalInconsistencyExceptions (avec la possibilité de les désactiver dans les versions).

3
Jens Ayton

Modifier: dans Xcode 4.2, les assertions sont désactivées par défaut pour les versions,

Maintenant NSAssert ne sera pas compilé dans votre code dans une version de build, mais vous pouvez le changer dans les paramètres de build


@ Mike Weller, il y a un problème dans votre réponse.

Une chose à noter est que NSAssert ne sera pas compilé dans votre code dans une version de build, donc ceci est généralement utilisé pour la vérification de l'intégrité pendant le développement.

En fait, NSAssert sera compilé dans votre code si vous n'ajoutez pas NS_BLOCK_ASSERTIONS dans vos fichiers de préfixes précompilés.

Dans la note technique TN2190, nous pouvons trouver:

Les macros comme NDEBUG pour désactiver l'assertion C ou NS_BLOCK_ASSERTIONS pour désactiver NSAssert de Foundation sont importantes à spécifier pour vos fichiers de préfixes précompilés

Ou vous pouvez lire celui-ci: Comment savoir si NSAssert est désactivé dans les versions?

2
likid1412

En général, les exceptions sont utilisées pour signaler des erreurs de programmation - ce sont des choses qui ne devraient pas se produire. Les erreurs sont utilisées pour signaler des conditions d'erreur qui peuvent survenir dans le fonctionnement normal du programme - des erreurs utilisateur, essentiellement, ou des conditions externes qui doivent être vraies mais qui ne le sont pas. Donc, essayer de supprimer un élément verrouillé dans un document peut être une erreur, et essayer de télécharger un fichier sans connexion Internet serait une erreur, mais essayer d'accéder à un élément non valide dans une collection serait une exception.

Les assertions sont généralement utilisées dans les tests et AFAIK n'est pas utilisé comme mécanisme général de gestion des erreurs comme les autres.

1
Chuck