Muszę o to zapytać, ponieważ: Jedyne, co rozpoznaję, to to, że jeśli asercja się nie powiedzie, aplikacja się zawiesza. Czy to jest powód, dla którego warto używać NSAssert? Albo jaka jeszcze jest z tego korzyść? I czy słuszne jest umieszczanie NSAssert tuż nad jakimkolwiek założeniem, które poczynię w kodzie, na przykład funkcji, która nigdy nie powinna otrzymywać -1 jako parametru, ale może mieć wartość -0,9 lub -1,1?
Naprawdę nie mogę rozmawiać z NSAssert, ale wyobrażam sobie, że działa podobnie do assert () w C.
assert () służy do wymuszania kontraktu semantycznego w kodzie. Co to znaczy, pytasz?
Cóż, jest tak, jak powiedziałeś: jeśli masz funkcję, która nigdy nie powinna otrzymać -1, możesz wymusić assert ():
A teraz zobaczysz coś takiego w dzienniku błędów (lub STDERR):
Dlatego nie tylko chroni przed potencjalnie złymi danymi wejściowymi, ale rejestruje je w użyteczny, standardowy sposób.
Aha, i przynajmniej w C assert () było makrem, więc możesz przedefiniować assert () jako no-op w swoim kodzie wydania. Nie wiem, czy tak jest w przypadku NSAssert (a nawet assert ()), ale kompilacja tych sprawdzeń była całkiem przydatna.
źródło
NSAssert
daje więcej niż tylko awarię aplikacji. Informuje o klasie, metodzie i wierszu, w którym wystąpiło potwierdzenie. Wszystkie asercje można również łatwo dezaktywować za pomocą NS_BLOCK_ASSERTIONS. Dzięki temu jest bardziej odpowiedni do debugowania. Z drugiej strony, rzucenieNSException
jedynego powoduje awarię aplikacji. Nie informuje również o lokalizacji wyjątku ani nie można go tak łatwo wyłączyć. Zobacz różnicę na poniższych obrazkach.Aplikacja ulega awarii, ponieważ asercja wywołuje również wyjątek, zgodnie z dokumentacją NSAssert :
NSAssert:
NSException:
źródło
NSException
Zapewnia mnóstwo okazji, aby dostosować wyjście powraca za pośrednictwemreason
iuserInfo
parametrów. Nie ma powodu, dla którego nie mógłbyś dodać nazwy klasy, selektora, informacji o wierszu ani niczego innego, co chcesz dodać, aby pomóc w debugowaniu. IMHO, używaszNSAssert
do celów debugowania podczas programowania, ale wyłączasz je do wysyłki; rzucasz,NSException
jeśli chcesz zostawić w asercji w kodzie wysyłkowym.Oprócz tego, co wszyscy powiedzieli powyżej, domyślnym zachowaniem
NSAssert()
(w przeciwieństwie do Cassert()
) jest wyrzucenie wyjątku, który można złapać i obsłużyć. Na przykład Xcode to robi.źródło
Aby wyjaśnić, jak ktoś wspomniał, ale nie w pełni wyjaśniono, powodem posiadania i używania potwierdzeń zamiast tworzenia niestandardowego kodu (na przykład robienie ifs i zgłaszanie wyjątku dla złych danych) jest to, że twierdzi, że POWINNO być wyłączone dla aplikacji produkcyjnych.
Podczas programowania i debugowania potwierdzenia są włączone, abyś mógł wychwycić błędy. Program zatrzyma się, gdy potwierdzenie zostanie ocenione jako fałszywe. Ale podczas kompilacji na potrzeby produkcyjne kompilator pomija kod potwierdzenia i w rzeczywistości sprawia, że program działa szybciej. Miejmy nadzieję, że do tego czasu naprawiłeś wszystkie błędy. W przypadku, gdy twój program nadal zawiera błędy podczas produkcji (kiedy asercje są wyłączone i program „pomija” asercje), twój program prawdopodobnie zakończy się awarią w innym miejscu.
Z pomocy NSAssert: "Asercje są wyłączone, jeśli zdefiniowano makro preprocesora NS_BLOCK_ASSERTIONS." Po prostu umieść makro w docelowym miejscu dystrybucji [tylko].
źródło
NSAssert
(i jego odpowiednik w standardowej biblioteceassert
) służą do wykrywania błędów programowania podczas programowania. Nigdy nie powinieneś mieć asercji, która zawodzi w produkcyjnej (wydanej) aplikacji. Możesz więc twierdzić, że nigdy nie przekazujesz liczby ujemnej do metody wymagającej argumentu dodatniego. Jeśli asercja kiedykolwiek zawiedzie podczas testowania, masz błąd. Jeśli jednak wartość, która jest przekazywana, jest wprowadzana przez użytkownika, należy przeprowadzić odpowiednią walidację danych wejściowych, zamiast polegać na potwierdzeniu w środowisku produkcyjnym (można ustawić #define dla kompilacji wydania, które wyłączająNSAssert*
.źródło
Twierdzenia są powszechnie używane do wymuszania zamierzonego użycia określonej metody lub elementu logiki. Powiedzmy, że piszesz metodę, która oblicza sumę dwóch liczb całkowitych większych od zera. Aby upewnić się, że metoda była zawsze używana zgodnie z przeznaczeniem, prawdopodobnie umieściłbyś asercję, która testuje ten warunek.
Krótka odpowiedź: wymuszają, że twój kod jest używany tylko zgodnie z przeznaczeniem.
źródło
Warto zauważyć, że oprócz sprawdzania w czasie wykonywania, programowanie potwierdzające jest ważną funkcją używaną podczas projektowania kodu na podstawie umowy.
Więcej informacji na temat stwierdzenia i projektowania na podstawie umowy można znaleźć poniżej:
Assertion (rozwój oprogramowania)
Zaprojektuj zgodnie z umową
Programowanie z asercjami
Zaprojektuj według umowy, na przykładzie [książka w miękkiej okładce]
źródło
Aby w pełni odpowiedzieć na jego pytanie, celem każdego typu potwierdzenia jest pomoc w debugowaniu. Bardziej wartościowe jest wychwycenie błędów u ich źródła, a następnie wyłapanie ich w debugerze, gdy powodują one awarie.
Na przykład, możesz przekazać wartość do funkcji, która oczekuje wartości z określonego zakresu. Funkcja może przechowywać wartość do późniejszego użycia, a przy późniejszym użyciu aplikacja ulega awarii. Stos wywołań widoczny w tym scenariuszu nie pokaże źródła złej wartości. Lepiej jest złapać złą wartość, gdy pojawia się, aby dowiedzieć się, kto przekazuje złą wartość i dlaczego.
źródło
NSAssert
powoduje awarię aplikacji, gdy pasuje do warunku. Jeśli nie pasuje do warunku, zostaną wykonane następne instrukcje. Poszukaj EX poniżej:Po prostu tworzę aplikację, aby przetestować, jakie jest zadanie
NSAssert
:w moim kodzie aplikacja nie ulegnie awarii, a przypadek testowy to:
anNum
> = 2 -> Aplikacja nie ulegnie awarii i możesz zobaczyć ciąg dziennika: „Ta instrukcja zostanie wykonana, gdy anNum <2” w oknie konsoli dziennika wyjściaanNum
<2 -> Aplikacja ulegnie awarii i nie widać ciągu dziennika: „Ta instrukcja zostanie wykonana, gdy anNum <2”źródło