2016-01-19 18 views
9

Dzięki Swift niektóre funkcje są oznaczone jako throws, co wymusza na programistach wywołanie funkcji wewnątrz bloku do - try catch. Ale w jaki sposób programista może poznać listę różnych wyjątków zgłaszanych przez tę funkcję?Jak uzyskać listę błędów zgłaszanych przez funkcję?

Jako odniesienie, tutaj jest wiersz kodu Java:

static void employeeAge(int age) throws MyExceptionA,MyExceptionB 

Tutaj jest jasne, że wyjątki są 2 MyExceptionA i MyExceptionB a deweloper może zdecydować, aby działać w różny sposób w zależności od błędu.

Czy możemy osiągnąć to samo na Swift?

+0

Unfortanely, trzeba sprawdzić Dokumentation (API). Bądź ostrożny, nie ma wyjątków, rzucanie, ale błąd rzucania. Jeśli szukasz sposobu na uporządkowanie przepływu kodu, użyj zamiast tego odpowiedniego sprawdzenia. Błąd rzucania rzucania jest ostatnią szansą na odzyskanie, nie możesz wyjść z wyjątku. – user3441734

+0

[Zobacz także powiązane pytanie i zaakceptowaną odpowiedź.] (Http://stackoverflow.com/questions/31977738/how-to-find-the-kind-of-errors-a-method-may-throw-and- catch-them-in-swift) – Suragch

Odpowiedz

4

Gdy docs Swift mówi funkcją throws, to znaczy, że rzuca ErrorType (Cocoa API zwykle NSError), a nie wyjątek.

Rozważmy następujący do-try-catch przepływu dla 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 zakończy się niepowodzeniem, ponieważ katalog dokumentów już istnieje. Zalogowaniu się dynamicType o error pokazuje, że w rzeczywistości jest NSError obiektu:

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 

Aby zobaczyć różne rodzaje błędów funkcja może throw, to musiałby zbadać error o informacje aby określić typ zgłaszanego błędu i jak radzić sobie z każdym błędem. W przypadku NSError będzie to jego domena, kod i opis.

W tym konkretnym przypadku katalog już istnieje w tej ścieżce, więc menedżer plików nie może utworzyć nowego katalogu. Przykładem innego powodu niepowodzenia tej operacji byłoby, gdyby menedżer plików nie miał prawa do zapisu. To byłby kod błędu 256.

+1

Poza tym, istnieje "czysty" błąd błyskawicy ... Jedynym wymaganiem jest, że błąd rzucania jest zgodny z protokołem ErrorType. Nie oznacza to, że jest to obiekt NSError. – user3441734

+0

@ user3441734 Nie widzę żadnych "czystych" błędów zgłaszanych w interfejsach API lub dokumentach Cocoa Touch, był to tylko przykład przy użyciu metody dostarczonej przez Apple. Czy możesz podać mi w Dokumentach przykład "czystego" błędu Swift? Dodatkowo, '' ErrorType' jest adoptowany przez 'NSError'.] (Https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_ErrorType_Protocol/index.html) – JAL

+0

Tak czy inaczej, nie ma różnicy rodzaje błędów, które rzucają. Wszystkie błędy będą miały typ 'NSError' lub będą zgodne z protokołem' ErrorType'. Musiałbyś przyjrzeć się opisowi błędu lub jego kodowi, aby dowiedzieć się, co poszło nie tak. – JAL

-1

Piszemy wzorzec po haczyku, aby wskazać, jakie błędy może obsłużyć klauzula.

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

sprawdzić błędy sekcja Podnośniki pracy nie przyłowu Swift Programming Language

+4

pytanie, w jaki sposób można uzyskać listę wszystkich możliwych błędów zgłaszanych przez funkcję. Jeśli nie znam tej listy, nie mogę określić, z jakimi mam do czynienia. – IgnazioC

0

Miałem dokładnie to samo pytanie co OP. Ponieważ nikt tak naprawdę nie odpowiedział na pytanie, o które prosił (a także ja), oto mój wkład.

W Swift 3 i Xcode 8.3.3 można wykonać następujące czynności w celu potraktowania poszczególnych wyjątków. Poniżej podam przykład z FileManager.

Najpierw będziesz miał tylko jeden blok catch, który wykryje błąd, który metoda rzuca na ciebie. Następnie rzucisz ten błąd jako NSError. W przeciwieństwie do protokołu Error w Swift, NSError jest klasą błędów REAL. Następnie możesz wyodrębnić kod tego błędu w instrukcji switch. Będziesz musiał wiedzieć, z której domeny metoda generuje błąd, a następnie znaleźć kody błędów w odpowiednim pliku nagłówkowym.

W poniższym przykładzie błędy związane z plikami są zgłaszane w NSCocoaErrorDomain, a kody błędów są zdefiniowane/wymienione w pliku Foundation/FoundationErrors.h.W moim komputerze, znajdują się one w

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

dla MacOS aplikacjach i na

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

dla iPhone apps.

Więc tutaj jest przykład:

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() 
    } 
} 

.localizedDescription zawiera przyjazny dla użytkownika wiadomości w języku Twojego użytkownika na temat tego błędu. Jeśli plik nie zostanie znaleziony powyżej, wydrukuje: The file “file” couldn’t be opened because there is no such file. w języku angielskim. Jest przeznaczony do użycia bezpośrednio w oknach dialogowych błędów, które prezentujesz swojemu użytkownikowi.

Można również znaleźć więcej informacji na temat tego, co zostanie zgłoszony błąd przy każdej domeny tutaj: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorObjectsDomains/ErrorObjectsDomains.html

Powiązane problemy