Chcę zrobić coś w Swift 2, do czego przywykłem w wielu innych językach: wyrzucić wyjątek środowiska wykonawczego z niestandardową wiadomością. Na przykład (w Javie):
throw new RuntimeException("A custom message here")
Rozumiem, że mogę zgłaszać typy wyliczeń zgodne z protokołem ErrorType, ale nie chcę definiować wyliczeń dla każdego typu zgłaszanego błędu. Idealnie, chciałbym móc jak najdokładniej naśladować powyższy przykład. Przyjrzałem się stworzeniu niestandardowej klasy, która implementuje protokół ErrorType, ale nie mogę nawet dowiedzieć się, czego wymaga ten protokół (zobacz dokumentację ). Pomysły?
Odpowiedzi:
Najprostszym podejściem jest prawdopodobnie zdefiniowanie jednego zwyczaju za
enum
pomocą tylko jednego, docase
którego jestString
dołączony:Lub od Swift 4:
Przykładowe użycie wyglądałoby tak:
Jeśli chcesz użyć istniejących
Error
typów, najbardziej ogólnym z nich będzie anNSError
, i możesz utworzyć metodę fabryczną, aby utworzyć i wyrzucić typ z niestandardową wiadomością.źródło
String
środkaerrorMessage
, jeśli tak, jak mam to zrobić?String
Kojarzy się tutaj zMyError.RuntimeError
(ustawiony na czasiethrow
), a zyskasz dostęp do go wcatch
(zlet errorMessage
).try!
, co nie jest tutaj używane. Rzeczywiście nie możesz nawet wykonać potencjalnie rzucającego sprawdzenia bez jakiegoś rodzajutry
. (Również ta część kodu jest przykładowym użyciem, a nie rzeczywistym rozwiązaniem).Najprostszym sposobem jest
String
dostosowanie się doError
:Następnie możesz po prostu rzucić ciąg:
Aby sam ciąg był
localizedString
błędem, możesz zamiast tego rozszerzyćLocalizedError
:źródło
localizedDescription
go samą struną?Redundant conformance of 'String' to protocol 'Error'
:(error.localizedDescription
po rzuceniu ciągu.Rozwiązanie @ nick-keets jest najbardziej eleganckie, ale załamało się dla mnie w celu testowym z następującym błędem czasu kompilacji:
Redundant conformance of 'String' to protocol 'Error'
Oto inne podejście:
I do użycia:
źródło
Sprawdź tę fajną wersję. Chodzi o to, aby zaimplementować protokoły String i ErrorType i użyć rawValue błędu.
Stosowanie:
źródło
as User.UserValidationError
pakietu.rawValue
. Jeśli jednak zamiast tego zaimplementowanoCustomStringConvertible
jakovar description: String { return rawValue }
, przydatne może być uzyskanie niestandardowych opisów przy użyciu składni wyliczenia bez konieczności przechodzenia przezrawValue
każde miejsce, w którym je drukujesz.Swift 4:
Jak na:
https://developer.apple.com/documentation/foundation/nserror
jeśli nie chcesz definiować niestandardowego wyjątku, możesz użyć standardowego obiektu NSError w następujący sposób:
Wydruki:
Umożliwia to dostarczenie niestandardowego ciągu, a także kodu numerycznego i słownika ze wszystkimi dodatkowymi danymi, których potrzebujesz, dowolnego typu.
Uwaga: zostało to przetestowane na systemie OS = Linux (Ubuntu 16.04 LTS).
źródło
Najprostsze rozwiązanie bez dodatkowych rozszerzeń, wyliczeń, klas itp .:
źródło
raise()
zamiastthrow
) zaklęciem, które jest trudne do zapamiętania. Porównaj swoje rozwiązanie zthrow Foo.Bar("baz")
lubthrow "foo"
pomnożone przez liczbę miejsc, w których zgłaszany jest wyjątek - IMO jednorazowa opłata za przedłużenie jednowierszowe lub wyliczenie jest znacznie lepsza niż rzeczy takie jakNSExceptionName
.postNotification
wymaga 2-3 paramów i jego selektor jest podobny do tego. Czy nadpisujeszNotification
i / lubNotificationCenter
w każdym projekcie, aby umożliwić akceptację mniejszej liczby parametrów wejściowych?String
celu uzyskania zgodnościError
jest zbyt zaskakujące lub jeśliMyError
wyliczenie jest zbyt niejasne (osobiście odpowiedziałbym twierdząco na oba i zamiast tego zrobiłbym osobny przypadek wyliczenia dla każdego błędu, tj.throw ThisTypeOfError.thisParticularCase
).Na podstawie odpowiedzi @Nick keets, oto bardziej kompletny przykład:
Pierwotnie opublikowane na moim swift blogu: http://eon.codes/blog/2017/09/01/throwing-simple-errors/
źródło
throw NSError(message: "err", code: 0)
domain
, niemessage
, prawda?W przypadku, gdy nie musisz łapać błędu i chcesz natychmiast zatrzymać aplikację, możesz użyć fatalError:
fatalError ("Custom message here")
źródło
Podoba mi się odpowiedź @ Alexander-Borisenko, ale zlokalizowany opis nie został zwrócony, gdy został złapany jako błąd. Wygląda na to, że zamiast tego musisz użyć LocalizedError:
Zobacz tę odpowiedź, aby uzyskać więcej informacji.
źródło