Je n'ai pas trop lu Swift, mais une chose que j'ai remarquée est qu'il n'y a pas d'exceptions. Alors, comment font-ils la gestion des erreurs dans Swift? Quelqu'un a-t-il trouvé quelque chose concernant la gestion des erreurs?
swift
error-handling
peko
la source
la source
Réponses:
Swift 2 et 3
Les choses ont un peu changé dans Swift 2, car il existe un nouveau mécanisme de gestion des erreurs, qui est un peu plus similaire aux exceptions mais différent en détail.
1. Indication de la possibilité d'erreur
Si la fonction / méthode veut indiquer qu'elle peut générer une erreur, elle doit contenir un
throws
mot clé comme celui-ciRemarque: il n'y a pas de spécification du type d'erreur que la fonction peut réellement générer. Cette déclaration indique simplement que la fonction peut lancer une instance de n'importe quel type implémentant ErrorType ou ne la lance pas du tout.
2. Appel d'une fonction susceptible de générer des erreurs
Pour appeler la fonction, vous devez utiliser le mot clé try, comme celui-ci
cette ligne devrait normalement être présente dans un bloc do-catch comme celui-ci
Remarque: la clause catch utilise toutes les fonctionnalités puissantes de la correspondance de motifs Swift, vous êtes donc très flexible ici.
Vous pouvez décider de propager l'erreur, si vous appelez une fonction de lancement à partir d'une fonction qui est elle-même marquée par le
throws
mot-clé:Vous pouvez également appeler la fonction de lancement en utilisant
try?
:De cette façon, vous obtenez la valeur de retour ou nil, si une erreur s'est produite. En utilisant cette méthode, vous n'obtenez pas l'objet d'erreur.
Ce qui signifie que vous pouvez également combiner
try?
avec des déclarations utiles telles que:ou
Enfin, vous pouvez décider que vous savez que l'erreur ne se produira pas réellement (par exemple parce que vous avez déjà vérifié les prérequis) et utiliser le
try!
mot-clé:Si la fonction génère réellement une erreur, vous obtiendrez une erreur d'exécution dans votre application et l'application se terminera.
3. Lancer une erreur
Pour lancer une erreur, vous utilisez un mot-clé throw comme celui-ci
Vous pouvez lancer tout ce qui est conforme au
ErrorType
protocole. Pour commencer, ilNSError
est conforme à ce protocole, mais vous aimeriez probablement utiliser enum-basedErrorType
qui vous permet de regrouper plusieurs erreurs liées, potentiellement avec des données supplémentaires, comme celle-ciLes principales différences entre le nouveau mécanisme d'erreur Swift 2 & 3 et les exceptions de style Java / C # / C ++ sont les suivantes:
do-catch
+try
+defer
vs traditionnelletry-catch-finally
syntaxe .do-catch
bloc n'attrapera aucune NSException, et vice versa, pour cela vous devez utiliser ObjC.NSError
conventions de la méthode Cocoa consistant à retournerfalse
(pourBool
renvoyer des fonctions) ounil
(pourAnyObject
renvoyer des fonctions) et à transmettreNSErrorPointer
avec les détails de l'erreur.En tant que sucre syntaxique supplémentaire pour faciliter la gestion des erreurs, il existe deux autres concepts
defer
mot-clé) qui vous permettent d'obtenir le même effet que les blocs finally en Java / C # / etcguard
mot-clé) qui vous permet d'écrire un peu moins de code if / else que dans le code de vérification / signalisation d'erreur normal.Swift 1
Erreurs d'exécution:
Comme Leandros le suggère pour gérer les erreurs d'exécution (comme les problèmes de connectivité réseau, l'analyse des données, l'ouverture de fichier, etc.), vous devez utiliser
NSError
comme vous l'avez fait dans ObjC, car la Fondation, AppKit, UIKit, etc. signalent leurs erreurs de cette manière. C'est donc plus une question de cadre que de langage.Un autre modèle fréquemment utilisé est celui des blocs de succès / échec de séparateur comme dans AFNetworking:
Toujours le bloc d'échec a fréquemment reçu l'
NSError
instance, décrivant l'erreur.Erreurs de programmeur:
Pour les erreurs de programmeur (comme l'accès hors limites à l'élément de tableau, les arguments non valides passés à un appel de fonction, etc.), vous avez utilisé des exceptions dans ObjC. Swift langue ne semble pas avoir de prise en charge linguistique des exceptions (comme
throw
,catch
, etc mot - clé). Cependant, comme la documentation le suggère, il s'exécute sur le même runtime qu'ObjC, et vous pouvez donc toujours lancerNSExceptions
comme ceci:Vous ne pouvez tout simplement pas les attraper en Swift pur, bien que vous puissiez opter pour intercepter les exceptions dans le code ObjC.
La question est de savoir si vous devez lever des exceptions pour les erreurs du programmeur, ou plutôt utiliser des assertions comme le suggère Apple dans le guide du langage.
la source
fatalError(...)
est le même aussi bien.Mise à jour du 9 juin 2015 - Très important
Swift 2.0 est livré avec
try
,throw
et descatch
mots - clés et le plus excitant est la suivante :Extrait de: Apple Inc. «Utilisation de Swift avec Cocoa et Objective-C (version préliminaire de Swift 2)». iBooks.
Exemple: (du livre)
L'équivalent en swift sera:
Lancer une erreur:
Sera automatiquement propagé à l'appelant:
D'après les livres Apple, The Swift Programming Language, il semble que les erreurs devraient être gérées à l'aide d'énumération.
Voici un exemple du livre.
De: Apple Inc. «The Swift Programming Language». iBooks. https://itun.es/br/jEUH0.l
Mettre à jour
Tiré des livres d'actualités Apple, "Utilisation de Swift avec Cocoa et Objective-C". Les exceptions d'exécution ne se produisent pas en utilisant des langages Swift, c'est pourquoi vous n'avez pas try-catch. À la place, vous utilisez le chaînage facultatif .
Voici un extrait du livre:
Extrait de: Apple Inc. «Utilisation de Swift avec Cocoa et Objective-C». iBooks. https://itun.es/br/1u3-0.l
Et les livres vous encouragent également à utiliser le modèle d'erreur cacao d'Objective-C (NSError Object)
Extrait de: Apple Inc. «Utilisation de Swift avec Cocoa et Objective-C». iBooks. https://itun.es/br/1u3-0.l
la source
Il n'y a pas d'exceptions dans Swift, similaire à l'approche d'Objective-C.
En développement, vous pouvez utiliser
assert
pour détecter les erreurs qui pourraient apparaître et qui doivent être corrigées avant de passer en production.L'
NSError
approche classique n'est pas modifiée, vous envoyez unNSErrorPointer
, qui se remplit.Bref exemple:
la source
f();g();
devientf(&err);if(err) return;g(&err);if(err) return;
pour le premier mois, puis il devient justef(nil);g(nil);hopeToGetHereAlive();
Le 'Swift Way' recommandé est:
Cependant, je préfère try / catch car je trouve cela plus facile à suivre car il déplace la gestion des erreurs vers un bloc séparé à la fin, cet arrangement est parfois appelé "Golden Path". Heureusement, vous pouvez le faire avec des fermetures:
Il est également facile d'ajouter une fonction de nouvelle tentative:
La liste de TryBool est:
Vous pouvez écrire une classe similaire pour tester une valeur renvoyée facultative au lieu d'une valeur booléenne:
La version TryOptional applique un type de retour non optionnel qui facilite la programmation ultérieure, par exemple 'Swift Way:
Utilisation de TryOptional:
Notez le déballage automatique.
la source
Edit: Bien que cette réponse fonctionne, ce n'est guère plus qu'Objective-C translittéré en Swift. Il a été rendu obsolète par les modifications apportées à Swift 2.0. La réponse de Guilherme Torres Castro ci-dessus est une très bonne introduction à la manière préférée de gérer les erreurs dans Swift. VOS
Il a fallu un peu de temps pour le comprendre, mais je pense que je l'ai compris. Cela semble moche cependant. Rien de plus qu'une peau fine sur la version Objective-C.
Appel d'une fonction avec un paramètre NSError ...
Ecriture de la fonction qui prend un paramètre d'erreur ...
la source
Emballage de base autour de l'objectif C qui vous donne la fonction try catch. https://github.com/williamFalcon/SwiftTryCatch
Utilisez comme:
la source
Ceci est une réponse de mise à jour pour swift 2.0. Je suis impatient d'avoir un modèle de gestion des erreurs riche en fonctionnalités, comme en java. Enfin, ils ont annoncé la bonne nouvelle. ici
par exemple :
la source
Comme Guilherme Torres Castro a dit, à Swift 2.0,
try
,catch
,do
peut être utilisé dans la programmation.Par exemple, dans la méthode de récupération de données CoreData, au lieu de le placer en
&error
tant que paramètre dans lemanagedContext.executeFetchRequest(fetchRequest, error: &error)
, il ne nous reste plus qu'à utiliser usemanagedContext.executeFetchRequest(fetchRequest)
, puis à gérer l'erreur avectry
,catch
( Apple Document Link )Si vous avez déjà téléchargé la version bêta de xcode7. Essayez de rechercher des erreurs de lancement dans la documentation et la référence d'API et choisissez le premier résultat affiché, cela donne une idée de base de ce qui peut être fait pour cette nouvelle syntaxe. Cependant, la documentation complète n'est pas encore publiée pour de nombreuses API.
Des techniques plus sophistiquées de gestion des erreurs peuvent être trouvées dans
la source
La gestion des erreurs est une nouvelle fonctionnalité de Swift 2.0. Il utilise les
try
,throw
et lescatch
mots clés.Voir l' annonce Apple Swift 2.0 sur le blog officiel Apple Swift
la source
Belle et simple bibliothèque pour gérer l'exception: TryCatchFinally-Swift
Comme quelques autres, il englobe les fonctionnalités d'exception de l'objectif C.
Utilisez-le comme ceci:
la source
À partir de Swift 2, comme d'autres l'ont déjà mentionné, la gestion des erreurs est mieux accomplie en utilisant les énumérations do / try / catch et ErrorType. Cela fonctionne assez bien pour les méthodes synchrones, mais un peu d'intelligence est nécessaire pour la gestion des erreurs asynchrones.
Cet article a une excellente approche de ce problème:
https://jeremywsherman.com/blog/2015/06/17/using-swift-throws-with-completion-callbacks/
Résumer:
puis, l'appel à la méthode ci-dessus serait le suivant:
Cela semble un peu plus propre que d'avoir un rappel errorHandler séparé passé à la fonction asynchrone, ce qui était la façon dont cela serait géré avant Swift 2.
la source
Ce que j'ai vu, c'est qu'en raison de la nature de l'appareil, vous ne voulez pas lancer un tas de messages de gestion d'erreurs cryptiques à l'utilisateur. C'est pourquoi la plupart des fonctions renvoient des valeurs facultatives, puis vous codez simplement pour ignorer l'option. Si une fonction revient à zéro, ce qui signifie qu'elle a échoué, vous pouvez afficher un message ou autre.
la source