Soll ich am Ende oder am Anfang super.initState aufrufen?

10

Ich bin verwirrt, wo ich das super.initSate()Flattern anrufen soll . In einigen Codebeispielen wird es am Anfang und in anderen am Ende aufgerufen. Ist da ein Unterschied?

Ich habe versucht, dies zu googeln, aber keine Erklärung für die Position dieses Funktionsaufrufs gefunden.

Welches ist richtig?

void initState() {
  super.initState();    
  //DO OTHER STUFF
}

oder

void initState() {    
  //DO OTHER STUFF
  super.initState();    
}
K Vij
quelle

Antworten:

4

Es ist wichtig für mixins (und deswegen auch für Sie )

Es ist ein Paradigma im Flutter-Framework, die Supermethode aufzurufen, wenn Lebenszyklusmethoden in a überschrieben werden State. Deshalb gibt es sogar deactivateeine mustCallSuperAnmerkung .
Darüber hinausmixin erwarten einige, dass Sie die Supermethoden dieser Lebenszyklusmethoden an einem bestimmten Punkt in der Funktion aufrufen.

Dies bedeutet , dass Sie sollten die Dokumentation und Anruf folgen super.dispose am Ende Ihrer disposeMethode , da mixins auf Stateim Rahmen erwarten , dass dies der Fall ist.
Zum Beispiel: TickerProviderStateMixinund am Ende behaupten :SingleTickerProviderStateMixin super.dispose

Alle Ticker müssen [..] entsorgt werden, bevor super.dispose () aufgerufen wird.

Ein weiteres Beispiel: AutomaticKeepAliveMixinFührt Logik in initStateund aus dispose.

Fazit

Beginnen Sie initStatemitsuper.initState und beenden Sie disposemit,super.dispose wenn Sie auf der einfachen und sicheren Seite sein möchten und mixins zu Ihrem hinzufügen möchten State.
Befolgen Sie außerdem die Dokumentation für andere Lebenszyklusmethoden (jede Methode, die Sie überschreiben State), da das Framework erwartet, dass Sie die in der Dokumentation beschriebenen Supermethoden aufrufen.

Daher sollten Sie Folgendes tun:

void initState() {
  super.initState();    
  //DO OTHER STUFF
}

Es ist jedoch nicht wirklich wichtig State, was ich im Folgenden erläutern werde, und selbst für Mixins, es ist nur wichtig für Aussagen, die nach dem urteilen, was ich finden konnte - es würde also Ihre Produktions-App nicht beeinträchtigen.

Es spielt keine Rolle für State

Ich denke , dass die letzten beiden Antworten von Pablo Barrera und CopsOnRoad sind irreführend , weil die Wahrheit der Sache ist , dass es wirklich keine Rolle und man nicht lange suchen müssen.

Die einzigen Aktionen , die super.initStateund super.disposein der nehmen StateKlasse selbst sind Behauptungen und da assert-Aussagen nur in ausgewertet wird Debug - Modus , spielt es keine Rolle , auf alle einmal baut Ihre Anwendung, dh im Produktionsmodus.


Im Folgenden werde ich Sie durch das, was super.initStateund was Sie super.disposetun State, führen. Dies ist der gesamte Code, der ausgeführt wird, wenn Sie keine zusätzlichen Mixins haben.

initState

Schauen wir uns genau an, in welchem ​​Code zuerst ausgeführt wird super.initState( Quelle ):

@protected
@mustCallSuper
void initState() {
  assert(_debugLifecycleState == _StateLifecycle.created);
}

Wie Sie sehen können, gibt es nur eine Bestätigung für den Lebenszyklus, mit der sichergestellt werden soll, dass Ihr Widget ordnungsgemäß funktioniert. Solange Sie super.initState irgendwo in Ihrem eigenen anrufen initState, sehen Sie, AssertionErrorob Ihr Widget nicht wie beabsichtigt funktioniert. Es spielt keine Rolle, ob Sie zuvor Maßnahmen ergriffen haben, da assertnur gemeldet werden soll, dass etwas in Ihrem Code ohnehin nicht stimmt, und Sie werden dies auch dann sehen, wenn Sie super.initStateganz am Ende Ihrer Methode aufrufen .

dispose

Die disposeMethode ist analog ( Quelle ):

@protected
@mustCallSuper
void dispose() {
  assert(_debugLifecycleState == _StateLifecycle.ready);
  assert(() {
    _debugLifecycleState = _StateLifecycle.defunct;
    return true;
  }());
}

Wie Sie sehen können, enthält es auch nur Zusicherungen, die die Überprüfung des Debug- Lebenszyklus behandeln. Der zweite asserthier ist ein netter Trick, da er sicherstellt, dass der _debugLifecycleStatenur im Debug-Modus geändert wird (da assert-Statements nur im Debug-Modus ausgeführt werden).
Dies bedeutet, dass Sie, solange Sie super.dispose irgendwo in Ihrer eigenen Methode aufrufen , keinen Wert verlieren, ohne dass Mixins zusätzliche Funktionen hinzufügen.

CreativeCreatorormaybenot
quelle
1
Flutter offizielle Dokumente sind nicht sehr gut :( Danke für Ihre Antwort :)
CopsOnRoad
Vielen Dank für Ihre Erklärung. Würde es Ihnen auch etwas ausmachen zu erklären, dass es nur eine Zeile in der initState()Methode gibt ? assert(...)Was ist also der Vorteil, wenn Sie die super.initState()Produktions-App aufrufen ?
CopsOnRoad
1
Vielen Dank. Jetzt macht es Sinn! Ich denke also, um auf der sicheren Seite zu sein und um eine gute Programmierpraxis zu erreichen, ist es gut, sie am Anfang des Codes zu belassen.
K Vij
@creativecreatorormaybenot Das bedeutet, dass das Flutter-Team nicht mehr im Kopf ist, wenn es mustCallSuperdiese Methode seit mehr als zwei Jahren anwendet, seit Flutter ins Leben gerufen wurde. Was ist der Vorteil, wenn Sie es dort platzieren, Sir?
CopsOnRoad
@creativecreatorormaybenot Auch wenn das Team es erstellt hat mixin, wird es dennoch eine einzige Aussage geben, initStatedie lautet assert(...): Welche Bedeutung hat es also, überhaupt super.initState()eine Produktions-App zu fordern ?
CopsOnRoad
3

super.initState()sollte immer die erste Zeile in Ihrer initStateMethode sein.

Aus Dokumenten:

initState (): Wenn Sie dies überschreiben, stellen Sie sicher, dass Ihre Methode mit einem Aufruf von super.initState () beginnt.

CopsOnRoad
quelle
2

Wie Sie in den Klassen des Frameworks sehen können, sollten Sie alles tun, nachdem das Widget initialisiert wurde, dh danach super.initState().

Ich würde logischerweise andersherum entsorgen, erst alles machen und dann anrufen super.dispose().

@override
void initState() {
  super.initState();
  // DO STUFF
}

@override
void dispose() {
  // DO STUFF
  super.dispose();
}
Pablo Barrera
quelle
Danke. Aber ich habe das in einigen Codebeispielen bemerkt. Es wird am Ende der initState-Methode aufgerufen ...
K Vij
Das habe ich gesagt
Pablo Barrera
0

initState wird standardmäßig aufgerufen, wenn ein neues statusbehaftetes Widget zu einem Widget-Baum hinzugefügt wird. Jetzt führt der super.initState die Standardimplementierung der Basisklasse Ihres Widgets durch. Wenn Sie vor super.initState etwas aufrufen, das von der Basisklasse abhängt, kann dies zu Problemen führen. Aus diesem Grund wird empfohlen, initState folgendermaßen aufzurufen:

@override
void initState() {
  super.initState();
  // DO STUFF
}
Anirudh Sharma
quelle
Die Argumentation ist etwas fehlerhaft, weil disposees das Gegenteil ist. Das Framework erwartet, dass Sie super.dispose am Ende anrufen , aber die Empfehlung ist korrekt.
CreativeCreatorormaybenot
Denn wenn Sie super.dispose aufrufen, bevor Sie die anderen Dinge entsorgen, können Komponenten, die von Ihrer Basisklasse abhängen, zusammenstoßen.
Anirudh Sharma