2016-01-19 10 views
9

Mit Swift sind jetzt einige Funktionen mit throws markiert, und dies zwingt die Entwickler, die Funktion innerhalb eines Blocks aufzurufen. Aber wie kann der Entwickler die Liste der verschiedenen Ausnahmen kennen, die von dieser Funktion ausgelöst werden?Wie bekomme ich die Liste der Fehler, die von einer Funktion ausgelöst werden?

Als Referenz hier ist eine Reihe von Java-Code:

static void employeeAge(int age) throws MyExceptionA,MyExceptionB 

Hier ist klar, dass die Ausnahmen sind 2 MyExceptionA und MyExceptionB und der Entwickler kann entscheiden, anders zu handeln, hängt von den Fehlern.

Können wir dasselbe auf Swift erreichen?

+0

Unfortanely, Sie haben dokumentation (API) zu überprüfen. Sei vorsichtig, es gibt keine Ausnahme werfen, sondern Fehler werfen. Wenn Sie nach einer Möglichkeit suchen, den Codefluss zu organisieren, verwenden Sie stattdessen die richtige Überprüfung. Fangwurffehler ist die letzte Chance, sich davon zu erholen, Sie können sich nicht von einer Ausnahme erholen. – user3441734

+0

[Siehe auch diese verwandte Frage und die akzeptierte Antwort.] (Http://stackoverflow.com/questions/31977738/how-to-find-the-kind-of-errors-a-method-may-throw-and- catch-sie-in-swift) – Suragch

Antwort

4

Wenn die Swift-Dokumentation sagt eine Funktion throws, bedeuten sie, dass es ein ErrorType wirft (in Cocoa-APIs in der Regel eine NSError), keine Ausnahme.

Betrachten Sie den folgenden do-try-catch Fluss für NSFileManager ‚s createDirectoryAtPath:

let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] 

do { 
    try NSFileManager.defaultManager().createDirectoryAtPath(documentsPath, withIntermediateDirectories: false, attributes: nil) 
} catch { 
    // 'error' variable automatically populated 
    print(error) 
    print(error.dynamicType) 
} 

createDirectoryAtPath fehl, weil das Dokumentenverzeichnis bereits vorhanden ist. Protokollierung der dynamicType des error zeigt, dass es in der Tat ein NSError Objekt:

Error Domain=NSCocoaErrorDomain Code=516 "The file “Documents” couldn’t be saved in the folder “35B0B3BF-D502-4BA0-A991-D07568AB87C6” because a file with the same name already exists." UserInfo={NSFilePath=/Users/jal/Library/Developer/CoreSimulator/Devices/E8A35774-C9B7-42F0-93F1-8103FBBC7118/data/Containers/Data/Application/35B0B3BF-D502-4BA0-A991-D07568AB87C6/Documents, NSUnderlyingError=0x7fa88bd14410 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}} 

NSError 

Um die verschiedenen Arten von Fehlern eine Funktion zu sehen throw, würden Sie die error Informationen prüfen müssen um den Typ des Fehlers zu bestimmen, der ausgelöst wird, und wie mit jedem Fehler umzugehen ist. Im Fall von NSError wäre dies die Domäne, der Code und die Beschreibung.

In diesem speziellen Fall existiert bereits ein Verzeichnis in diesem Pfad, sodass der Dateimanager kein neues Verzeichnis erstellen kann. Ein Beispiel für einen anderen Grund, warum diese Operation fehlschlagen könnte, wäre, wenn der Dateimanager keinen Schreibzugriff hätte. Das wäre der Fehlercode 256.

+1

Außer, es gibt 'pure' swift's Fehler ... Die einzige Voraussetzung ist, dass der Wurffehler dem ErrorType Protokoll entspricht. Es bedeutet nicht, dass es ein NSError-Objekt ist. – user3441734

+0

@ user3441734 Ich sehe keine "reinen" Fehler in den Cocoa Touch-APIs oder -Docs geworfen, dies war nur ein Beispiel mit einer von Apple bereitgestellten Methode. Kannst du mir ein Beispiel in den Docs eines "reinen" Swift-Fehlers geben? Darüber hinaus wird ['ErrorType' von' NSError' übernommen.] (Https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_ErrorType_Protocol/index.html) – JAL

+0

Wie auch immer, es gibt keine Unterschiede Arten von Fehlern werden geworfen. Alle Fehler würden vom Typ 'NSError' sein oder dem' ErrorType'-Protokoll entsprechen. Sie müssen sich die genaue Beschreibung oder den Fehlercode des Fehlers ansehen, um herauszufinden, was falsch gelaufen ist. – JAL

-1

Sie schreiben ein Muster nach catch, um anzugeben, welche Fehler diese Klausel verarbeiten kann.

do { 
    try expression 
    statements 
} catch pattern 1 { 
    statements 
} catch pattern 2 where condition { 
    statements 
} 

Siehe Abschnitt Fehlerbehandlung Verwenden von Do-Fang Swift Programming Language

+4

die Frage ist, wie bekomme ich die Liste aller möglichen Fehler, die von einer Funktion ausgelöst werden. Wenn ich die Liste nicht kenne, kann ich nicht angeben, mit welchen ich umgehen kann. – IgnazioC

0

Ich hatte genau die gleiche Frage wie das OP. Da niemand die Frage wirklich beantwortet hat (und ich auch), geht hier mein Beitrag.

In Swift 3 und Xcode 8.3.3 würden Sie wie folgt vorgehen, um die einzelnen Ausnahmen zu behandeln. Im Folgenden werde ich Ihnen ein Beispiel mit FileManager geben.

Zuerst haben Sie nur einen catch-Block, um den Fehler zu erfassen, den die Methode Ihnen zufügt. Dann werden Sie diesen Fehler als NSError auslösen. Im Gegensatz zum Fehlerprotokoll in Swift ist NSError eine REAL-Fehlerklasse. Dann können Sie den Code dieses Fehlers in einer switch-Anweisung extrahieren. Sie müssen wissen, von welcher Domäne diese Methode Fehler auslöst, und dann die Fehlercodes in der entsprechenden Header-Datei finden.

In meinem Beispiel unten werden die Dateifehler in der NSCOAErrorDomain ausgelöst und diese Fehlercodes sind in Foundation/FoundationErrors.h definiert/aufgelistet.In meinem Computer, werden sie bei

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/FoundationErrors.h 

für Mac OS-Anwendungen und bei

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/Foundation.framework/Headers/ 

für iPhone-Apps entfernt.

So, hier ist ein Beispiel:

let home = FileManager.default.homeDirectoryForCurrentUser 
let file = home.appendingPathComponent("file") 
do { 
    let loadedString = try String(contentsOf: file) 
} 
catch { 
    let realError = error as NSError // As weird as it looks, Xcode actually wants this forced conversion 
    print(realError.localizedDescription) 
    switch realError.code { 
    case 257: // No permission 
     handleNoPermission() 
    case 260: // File not found 
     handleFileNotFound() 
    default: 
     handleUndefinedError() 
    } 
} 

Die .localizedDescription enthält eine benutzerfreundliche Nachricht in der Sprache Ihres Benutzers zu diesem Fehler. Wenn die Datei oben nicht gefunden wird, wird The file “file” couldn’t be opened because there is no such file. in Englisch gedruckt. Es soll direkt in den Fehlerdialogen verwendet werden, die Sie Ihrem Benutzer präsentieren.

Sie können auch weitere Informationen finden, welche Fehler von jeder Domain hier geworfen wird: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html