Nie czytałem zbyt wiele w Swift, ale zauważyłem, że nie ma wyjątków. Jak więc radzą sobie z obsługą błędów w Swift? Czy ktoś znalazł coś związanego z obsługą błędów?
swift
error-handling
peko
źródło
źródło
Odpowiedzi:
Swift 2 i 3
W Swift 2 wszystko się nieco zmieniło, ponieważ wprowadzono nowy mechanizm obsługi błędów, który jest nieco bardziej podobny do wyjątków, ale różni się szczegółowo.
1. Wskazanie możliwości wystąpienia błędu
Jeśli funkcja / metoda chce wskazać, że może zgłosić błąd, powinna zawierać
throws
takie słowo kluczoweUwaga: nie ma specyfikacji rodzaju błędu, który funkcja może faktycznie wyrzucić. Ta deklaracja po prostu stwierdza, że funkcja może wyrzucić instancję dowolnego typu implementującą ErrorType lub w ogóle nie rzuca.
2. Wywoływanie funkcji, która może zgłaszać błędy
Aby wywołać funkcję, musisz użyć słowa kluczowego try, takiego jak ten
ta linia powinna normalnie występować w bloku catch-catch w ten sposób
Uwaga: klauzula catch wykorzystuje wszystkie zaawansowane funkcje dopasowania wzoru Swift, dzięki czemu jesteś bardzo elastyczny.
Możesz zdecydować się na propagowanie błędu, jeśli wywołujesz funkcję rzucania z funkcji, która sama jest oznaczona
throws
słowem kluczowym:Alternatywnie możesz wywołać funkcję rzucania za pomocą
try?
:W ten sposób otrzymasz albo wartość zwracaną, albo zero, jeśli wystąpi jakikolwiek błąd. W ten sposób nie otrzymujesz obiektu błędu.
Co oznacza, że możesz także łączyć się
try?
z przydatnymi stwierdzeniami, takimi jak:lub
Na koniec możesz zdecydować, że wiesz, że błąd faktycznie nie wystąpi (np. Ponieważ już sprawdziłeś, czy są wymagane) i użyć
try!
słowa kluczowego:Jeśli funkcja faktycznie zgłasza błąd, wówczas w aplikacji pojawi się błąd czasu wykonywania, a aplikacja zostanie zakończona.
3. Zgłaszanie błędu
Aby zgłosić błąd, użyj słowa kluczowego rzutu takiego jak ten
Możesz rzucać wszystko, co jest zgodne z
ErrorType
protokołem. Na początekNSError
jest zgodny z tym protokołem, ale prawdopodobnie chciałbyś skorzystać z metody wyliczania,ErrorType
która umożliwia grupowanie wielu powiązanych błędów, potencjalnie z dodatkowymi częściami danych, takimi jak tenGłówne różnice między nowym mechanizmem błędów Swift 2 i 3 a wyjątkami w stylu Java / C # / C ++ są następujące:
do-catch
+try
+defer
vs. tradycyjnytry-catch-finally
składnią .do-catch
blok nie złapie żadnego wyjątku NSEx i vice versa, do tego musisz użyć ObjC.NSError
konwencjami metod Cocoa dotyczącymi zwracania albofalse
(dlaBool
zwracanych funkcji) albonil
(dlaAnyObject
zwracanych funkcji) i przekazywaniaNSErrorPointer
ze szczegółami błędu.Jako dodatkowy cukier syntetyczny ułatwiający obsługę błędów, istnieją jeszcze dwie koncepcje
defer
słowa kluczowego), które pozwalają osiągnąć ten sam efekt, co ostatecznie bloki w Javie / C # / itpguard
słowa kluczowego), która pozwala napisać niewiele mniej kodu if / else niż w normalnym kodzie sprawdzania / sygnalizacji błędówSzybki 1
Błędy czasu wykonania:
Jak sugeruje Leandros do obsługi błędów środowiska wykonawczego (takich jak problemy z połączeniem sieciowym, analizowanie danych, otwieranie pliku itp.), Powinieneś używać
NSError
tak jak w ObjC, ponieważ Foundation, AppKit, UIKit itp. Zgłaszają swoje błędy w ten sposób. Więc jest to bardziej kwestia frameworka niż języka.Innym częstym wzorcem, który jest używany, są bloki sukcesu / awarii separatora, takie jak w AFNetworking:
Nadal często otrzymywana jest blokada awarii
NSError
opisująca błąd.Błędy programatora:
W przypadku błędów programisty (takich jak przekroczenie granic elementu tablicy, niepoprawne argumenty przekazane do wywołania funkcji itp.) Zastosowano wyjątki w ObjC. Język Swift nie wydaje się mieć żadnego wsparcia językowego dla wyjątkami (jak
throw
,catch
itp słów kluczowych). Jednak, jak sugeruje dokumentacja, działa on w tym samym środowisku uruchomieniowym co ObjC, dlatego nadal możesz rzucać wNSExceptions
ten sposób:Po prostu nie możesz ich złapać w czystym Swift, chociaż możesz zdecydować się na łapanie wyjątków w kodzie ObjC.
Pytanie brzmi, czy należy zgłaszać wyjątki dla błędów programisty, czy raczej stosować twierdzenia, jak sugeruje Apple w przewodniku językowym.
źródło
fatalError(...)
jest taka sama, jak również.Aktualizacja 9 czerwca 2015 r. - Bardzo ważne
Swift 2.0 wyposażony
try
,throw
orazcatch
słów kluczowych i najbardziej ekscytujące jest:Fragment: Apple Inc. „Używanie Swift z kakao i Objective-C (wstępna wersja Swift 2)”. iBooks.
Przykład: (z książki)
Odpowiednikiem w swift będzie:
Zgłaszanie błędu:
Zostaną automatycznie propagowane do dzwoniącego:
Z książek Apple, The Swift Programming Language, wydaje się, że błędy powinny być rozwiązywane za pomocą enum.
Oto przykład z książki.
Od: Apple Inc. „Swift Programming Language”. iBooks. https://itun.es/br/jEUH0.l
Aktualizacja
Z książek prasowych Apple „Używanie Swift z kakao i Objective-C”. Wyjątki czasu wykonywania nie występują przy użyciu szybkich języków, dlatego nie masz opcji catch-catch. Zamiast tego używasz opcjonalnego łączenia .
Oto fragment książki:
Fragment: Apple Inc. „Używanie Swift z kakao i Objective-C”. iBooks. https://itun.es/br/1u3-0.l
Książki zachęcają również do korzystania ze wzoru błędu kakao z Objective-C (NSError Object)
Fragment: Apple Inc. „Używanie Swift z kakao i Objective-C”. iBooks. https://itun.es/br/1u3-0.l
źródło
W Swift nie ma wyjątków, podobnych do podejścia Celu C.
W fazie projektowania można użyć
assert
do wychwycenia wszelkich błędów, które mogą się pojawić, i należy je naprawić przed przejściem do produkcji.Klasyczne
NSError
podejście się nie zmienia, wysyłasz wiadomośćNSErrorPointer
, która zostaje zapełniona.Krótki przykład:
źródło
f();g();
staje sięf(&err);if(err) return;g(&err);if(err) return;
przez pierwszy miesiąc, a potem staje sięf(nil);g(nil);hopeToGetHereAlive();
Zalecany „Swift Way” to:
Jednak wolę try / catch, ponieważ łatwiej jest mi naśladować, ponieważ przesuwa on obsługę błędów do osobnego bloku na końcu, takie ustawienie jest czasem nazywane „Złotą Ścieżką”. Na szczęście możesz to zrobić za pomocą zamknięć:
Łatwo jest również dodać funkcję ponawiania:
Lista dla TryBool to:
Możesz napisać podobną klasę do testowania opcjonalnej wartości zwracanej zamiast wartości Bool:
Wersja TryOptional wymusza nie opcjonalny typ zwrotu, który ułatwia późniejsze programowanie, np. „Swift Way:
Korzystanie z TryOptional:
Uwaga automatyczne rozpakowywanie.
źródło
Edycja: Chociaż ta odpowiedź działa, jest to niewiele więcej niż Cel-C transliterowany na Swift. Został on przestarzały przez zmiany w Swift 2.0. Powyższa odpowiedź Guilherme Torres Castro stanowi bardzo dobre wprowadzenie do preferowanego sposobu obsługi błędów w Swift. VOS
Trochę to rozgryzłem, ale myślę, że to zrobiłem. Wydaje się to brzydkie. Nic więcej niż cienka skóra nad wersją Objective-C.
Wywoływanie funkcji z parametrem NSError ...
Zapisywanie funkcji, która przyjmuje parametr błędu ...
źródło
Podstawowe opakowanie wokół celu C, które daje funkcję try catch. https://github.com/williamFalcon/SwiftTryCatch
Użyj jak:
źródło
To jest odpowiedź na aktualizację dla Swift 2.0. Nie mogę się doczekać bogatego w funkcje modelu obsługi błędów jak w Javie. W końcu ogłosili dobre wieści. tutaj
np .:
źródło
Jak powiedział Guilherme Torres Castro, w Swift 2.0,
try
,catch
,do
mogą być wykorzystywane w programowaniu.Na przykład, w CoreData metodę pobierania danych, zamiast umieścić
&error
jako parametr domanagedContext.executeFetchRequest(fetchRequest, error: &error)
, teraz musimy tylko chcesz używaćmanagedContext.executeFetchRequest(fetchRequest)
, a następnie z obsługi błędutry
,catch
( jabłko Document Link )Jeśli już pobrałeś xcode7 Beta. Spróbuj wyszukać błędy związane z rzucaniem w dokumentacji i dokumentacji API i wybierz pierwszy pokazujący wynik, daje to podstawowe wyobrażenie o tym, co można zrobić dla tej nowej składni. Jednak pełna dokumentacja nie jest jeszcze opublikowana dla wielu interfejsów API.
Bardziej wymyślne techniki obsługi błędów można znaleźć w
źródło
Obsługa błędów to nowa funkcja Swift 2.0. Wykorzystuje on
try
,throw
icatch
słowa kluczowe.Zobacz ogłoszenie Apple Swift 2.0 na oficjalnym blogu Apple Swift
źródło
Ładna i prosta biblioteka do obsługi wyjątku: TryCatchFinally-Swift
Podobnie jak kilka innych, obejmuje on funkcje celu wyjątku C.
Użyj tego w ten sposób:
źródło
Począwszy od Swift 2, jak już wspomnieli inni, obsługa błędów najlepiej realizować za pomocą wyliczeń do / try / catch i ErrorType. Działa to całkiem dobrze w przypadku metod synchronicznych, ale do obsługi błędów asynchronicznych wymagana jest spryt.
Ten artykuł ma świetne podejście do tego problemu:
https://jeremywsherman.com/blog/2015/06/17/using-swift-throws-with-completion-callbacks/
Podsumowując:
wówczas wywołanie powyższej metody wyglądałoby następująco:
Wydaje się to nieco czystsze niż oddzielne wywołanie zwrotne errorHandler przekazane do funkcji asynchronicznej, tak było to obsługiwane przed wersją Swift 2.
źródło
Widziałem, że ze względu na naturę urządzenia nie chcesz rzucać użytkownikowi wielu tajemniczych komunikatów o błędach. Dlatego większość funkcji zwraca wartości opcjonalne, po prostu kodujesz, aby zignorować opcjonalne. Jeśli funkcja wróci zero, co oznacza, że się nie powiodła, możesz wstawić wiadomość lub cokolwiek innego.
źródło