To ma znaczenie dla mixin
s (a także z tego powodu dla ciebie )
Jest to paradygmat w ramach Flutter do wywołania metody super-gdy przesłanianie metod cyklu życia w krótkim czasie State
. Dlatego deactivate
ma nawet mustCallSuper
adnotację .
Ponadto niektórzy mixin
oczekują, że wywołasz super metody tych metod cyklu życia w określonym punkcie funkcji.
Oznacza to, że należy postępować zgodnie z dokumentacją i wezwanie super.dispose
na końcu swojej dispose
metody, ponieważ mixin
ów na State
w ramach spodziewać się, że jest to przypadek.
Na przykład: TickerProviderStateMixin
a assert na końcu:SingleTickerProviderStateMixin
super.dispose
Wszystkie znaczniki muszą […] zostać usunięte przed wywołaniem super.dispose ().
Kolejny przykład: AutomaticKeepAliveMixin
wykonuje logikę w initState
i dispose
.
Wniosek
Start Your initState
zsuper.initState
i zakończyć dispose
sięsuper.dispose
, jeśli chcesz być na łatwej i bezpiecznej stronie dodanie mixin
s do swojej State
.
Ponadto postępuj zgodnie z dokumentacją dotyczącą innych metod cyklu życia (dowolnej metody, którą zastąpisz State
), ponieważ środowisko będzie oczekiwać, że wywołasz metody super, jak opisano w dokumentacji.
Dlatego należy wykonać następujące czynności:
void initState() {
super.initState();
//DO OTHER STUFF
}
Jednak tak naprawdę nie ma to znaczenia State
, co wyjaśnię poniżej, a nawet dla mixin, ma znaczenie tylko dla stwierdzeń na podstawie tego, co mogłem znaleźć - więc nie wpłynie to na twoją aplikację produkcyjną.
To nie ma znaczenia State
Myślę, że dwie poprzednie odpowiedzi Pabla Barrery i CopsOnRoad są mylące, ponieważ prawda jest taka, że to naprawdę nie ma znaczenia i nie trzeba daleko szukać.
Jedyne czynności, które super.initState
i super.dispose
biorą w State
klasie sama są twierdzenia , a od assert
-statements są oceniane tylko w trybie debugowania , to nie ma znaczenia w ogóle raz kompilacja aplikacji, czyli w trybie produkcyjnym.
Poniżej poprowadzę cię przez to, co super.initState
i co super.dispose
robisz State
, czyli cały kod, który zostanie wykonany, gdy nie będziesz mieć dodatkowych miksów.
initState
Przyjrzyjmy się dokładnie, jaki kod jest super.initState
najpierw wykonywany ( źródło ):
@protected
@mustCallSuper
void initState() {
assert(_debugLifecycleState == _StateLifecycle.created);
}
Jak widać, istnieje tylko stwierdzenie dotyczące cyklu życia, a jego celem jest zapewnienie prawidłowego działania widgetu. Tak długo, jak dzwonisz super.initState
gdzieś we własnym zakresie initState
, zobaczysz komunikat, AssertionError
czy widżet nie działa zgodnie z przeznaczeniem. Nie ma znaczenia, czy podjąłeś jakieś wcześniejsze działania, ponieważ assert
ma to na celu wyłącznie zgłoszenie, że coś w twoim kodzie i tak jest złe i zobaczysz to, nawet jeśli zadzwonisz super.initState
na samym końcu metody.
dispose
dispose
Sposób analogiczny ( źródło )
@protected
@mustCallSuper
void dispose() {
assert(_debugLifecycleState == _StateLifecycle.ready);
assert(() {
_debugLifecycleState = _StateLifecycle.defunct;
return true;
}());
}
Jak widać, zawiera także tylko twierdzenia, które obsługują sprawdzanie cyklu życia debugowania . Drugi assert
tutaj jest fajną sztuczką, ponieważ zapewnia, że _debugLifecycleState
zmienia się tylko w trybie debugowania (ponieważ assert
-statements są wykonywane tylko w trybie debugowania).
Oznacza to, że dopóki zadzwonisz super.dispose
gdzieś własną metodą, nie stracisz żadnej wartości bez dodania dodatkowej funkcjonalności przez mixiny.
initState()
metodzieassert(...)
, więc jaka jest korzyść z nawet wywołaniasuper.initState()
aplikacji produkcyjnej?mustCallSuper
tę metodę od ponad 2 lat, odkąd Flutter powstał. Jaka jest korzyść z umieszczenia go tutaj?mixin
, nadal tam będzie jeden rachunek w tyminitState
co jestassert(...)
, więc co to znaczenie nawet dzwoniącsuper.initState()
do aplikacji produkcji?super.initState()
powinien zawsze być pierwszym wierszem w TwojejinitState
metodzie.Z dokumentów:
źródło
Jak widać w klasach z frameworka, powinieneś zrobić wszystko po zainicjowaniu widgetu, czyli po
super.initState()
.W przypadku wyrzucenia byłoby logicznie w inny sposób, najpierw zrobić wszystko, a następnie zadzwonić
super.dispose()
.źródło
initState wywoływane domyślnie za każdym razem, gdy do drzewa widżetów dodawany jest nowy widget stanowy. Teraz super.initState wykonuje domyślną implementację klasy podstawowej widgetu. Jeśli wywołasz coś przed super.initState, która zależy od klasy podstawowej, może to powodować problem. Dlatego zaleca się, aby wywoływać initState w następujący sposób:
źródło
dispose
jest odwrotnie. Struktura oczekuje, że zadzwoniszsuper.dispose
na końcu , ale zalecenie jest poprawne.