Objective-C: Assertion vs. Exception vs. Error

W Cocoa, kiedy należy użyć NSAssert, NSException, NSError?

Oto co sobie myślałem:

NSAssert - podczas tworzenia dowolnego programu klienckiego używanego dla własnych korzyści programistów, aby dwukrotnie sprawdzić reguły, konwencje, założenia lub warunki wstępne i warunki końcowe?

NSException - podczas tworzenia biblioteki innej firmy na rzecz innych programistów, którzy używają tej biblioteki, tak aby od razu wiedzieli, kiedy Dane wejściowe są inwalida?

NSError - podczas łączenia się z zewnętrznym systemem, aby uzyskać dane, takie jak plik, baza danych lub usługa internetowa, która nie jest gwarantowana, aby dać mi wynik?

Author: Michael Currie, 2011-02-16

4 answers

An NSAssert wyrzuci wyjątek, gdy się nie powiedzie. Tak więc NSAssert ma być krótkim i łatwym sposobem na napisanie i sprawdzenie wszelkich założeń, które poczyniłeś w swoim kodzie. Nie jest to (moim zdaniem) alternatywa dla wyjątków, tylko skrót. Jeśli twierdzenie nie powiedzie się, to coś poszło strasznie nie tak w Twoim kodzie i program nie powinien być kontynuowany.

Należy zauważyć, że NSAssert nie zostanie skompilowany do kodu w kompilacji release, więc jest to zwykle używane do sprawdzanie stanu zdrowia psychicznego podczas rozwoju. W rzeczywistości używam niestandardowego makra assert, które jest zawsze aktywne.

Czasy, kiedy @throw Twój własny NSException są takie, kiedy zdecydowanie chcesz go w kompilacji release, a także w takich rzeczach, jak biblioteki publiczne/interfejs, gdy niektóre argumenty są nieprawidłowe lub zostałeś wywołany nieprawidłowo. Zauważ, że nie jest tak naprawdę standardową praktyką, aby @catch był wyjątkiem i kontynuować uruchamianie aplikacji. Jeśli spróbujesz tego ze standardem Apple biblioteki (na przykład Podstawowe Dane) złe rzeczy mogą się zdarzyć. Podobnie jak assert, jeśli zostanie wyrzucony wyjątek, aplikacja powinna zakończyć się dość szybko, ponieważ oznacza to, że gdzieś jest błąd programowania.

NSErrors powinny być używane w bibliotekach / interfejsach w przypadku błędów, które nie są błędami programowania i z których można je odzyskać. Możesz podać informacje/kody błędów dzwoniącemu i może on obsłużyć błąd w sposób czysty, ostrzec użytkownika w razie potrzeby i kontynuować egzekucja. Zazwyczaj dotyczy to błędów typu file-not-found lub innych błędów innych niż fatalne.

 98
Author: Mike Weller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-15 22:31:51

Konwencja w Cocoa jest taka, że wyjątek wskazuje na błąd programisty. Wiele kodu, włączając w to framework, nie jest zaprojektowanych do poprawnego działania po wyrzuceniu wyjątku.

Każdy rodzaj błędu, który powinien być odzyskiwalny, jest reprezentowany przez NSError. Istnieje również system prezentacji NSError s użytkownikowi. Jak mówisz, jest to głównie przydatne dla omylnych zasobów zewnętrznych.

Koncepcyjnie, twierdzenie jest twierdzeniem, że dany predykat zawsze ocenia się na true; jeśli nie działa, program jest zepsuty. Podczas gdy jej zachowanie można modyfikować, rodzina NSAssert jest domyślnie wygodnym sposobem rzucania NSInternalInconsistencyExceptions (z opcją wyłączenia ich w Release buildach).

 3
Author: Jens Ayton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-15 21:36:09

Edytuj: W Xcode 4.2 asercje są domyślnie wyłączone dla wersji kompilacji,

Teraz NSAssert nie będzie kompilowany do Twojego kodu w release build , ale możesz go zmienić w build settings


@Mike Weller, w twojej odpowiedzi jest jeden błąd.

Należy zauważyć, że NSAssert nie zostanie skompilowany do kodu w kompilacji release , więc jest to zwykle używane do sprawdzania zdrowego rozsądku podczas rozwój.

Właściwie, NSAssert zostanie skompilowany do kodu, jeśli nie dodasz NS_BLOCK_ASSERTIONS do wstępnie skompilowanych plików z prefiksem.

W uwadze technicznej TN2190 możemy znaleźć:

Makra takie jak NDEBUG, aby wyłączyć C assert lub NS_BLOCK_ASSERTIONS, aby wyłączyć Nsassert Fundacji są ważne, aby określić dla wstępnie skompilowanych plików z prefiksem

Lub możesz przeczytać ten:Jak sprawdzić, czy NSAssert jest wyłączony w release builds?

 2
Author: likid1412,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:25

Ogólnie rzecz biorąc, wyjątki są używane do sygnalizowania błędów programisty - są to rzeczy, które nie powinny się wydarzyć. Błędy są używane do sygnalizowania warunków błędów, które mogą pojawić się w normalnym działaniu programu-błędów użytkownika, w zasadzie lub warunków zewnętrznych, które muszą być prawdziwe, ale mogą nie być. Tak więc próba usunięcia jakiegoś zablokowanego elementu w dokumencie może być błędem, a próba pobrania pliku bez połączenia z Internetem byłaby błędem, ale próba uzyskania dostępu do nieprawidłowego elementu w dokumencie kolekcja byłaby wyjątkiem.

Twierdzenia są zwykle używane w testowaniu, a AFAIK nie są używane jako ogólny mechanizm obsługi błędów, jak inne.

 1
Author: Chuck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-15 21:33:17