Dois-je appeler super.initState à la fin ou au début?

10

Je ne sais pas où appeler le super.initSate()flutter? Dans certains exemples de code, il est appelé au début et dans d'autres à la fin. Y a-t-il une différence?

J'ai essayé de google ceci mais n'ai trouvé aucune explication sur la position de cet appel de fonction.

Laquelle est correcte?

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

ou

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

Réponses:

4

Cela compte pour mixins (et à cause de cela pour vous aussi)

C'est un paradigme dans le cadre Flutter d'appeler la super méthode lors de la substitution des méthodes de cycle de vie dans a State. C'est pourquoi a même deactivateune mustCallSuperannotation .
De plus , certains mixins'attendent à ce que vous appeliez les super méthodes de ces méthodes de cycle de vie à un point particulier de la fonction.

Cela signifie que vous devez suivre la documentation et l' appel super.dispose à la fin de votre disposeméthode , car mixins sur Statedans le cadre attendent à ce que ce soit le cas.
Par exemple: TickerProviderStateMixinet affirmez à la fin:SingleTickerProviderStateMixin super.dispose

Tous les tickers doivent [..] être supprimés avant d'appeler super.dispose ().

Autre exemple: AutomaticKeepAliveMixinexécute la logique dans initStateet dispose.

Conclusion

Commencez votre initStateavecsuper.initState et terminez votre disposeavecsuper.dispose si vous voulez être sur le côté facile et sûr ajouter mixins à votre State.
De plus, suivez la documentation des autres méthodes de cycle de vie (toute méthode dans laquelle vous écrasez State) car le framework attendra que vous appeliez les super méthodes comme décrit dans la documentation.

Ainsi, voici ce que vous devez faire:

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

Cependant, cela n'a pas vraiment d' importance pour State, ce que je vais expliquer dans la suite et même pour les mixins, cela n'a d'importance que pour les affirmations à en juger par ce que j'ai pu trouver - donc cela n'affecterait pas votre application de production.

Peu importe pour State

Je pense que les deux réponses précédentes de Pablo Barrera et CopsOnRoad sont trompeuses parce que la vérité est que cela n'a pas vraiment d'importance et que vous n'avez pas besoin de chercher loin.

Les seules actions super.initStateet super.disposeprennent dans la Stateclasse elle - même sont des affirmations et puisque assert-statements ne sont évaluées en mode débogage , il n'a pas d' importance du tout une fois construire votre application, soit en mode de production.


Dans ce qui suit, je vais vous guider à travers quoi super.initStateet super.disposefaire State, qui est tout le code qui sera exécuté lorsque vous n'aurez pas de mixins supplémentaires.

initState

Voyons exactement quel code est exécuté en super.initStatepremier ( source ):

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

Comme vous pouvez le voir, il n'y a qu'une assertion de cycle de vie et le but est de s'assurer que votre widget fonctionne correctement. Donc, tant que vous appelez super.initState quelque part dans votre propre initState, vous verrez un AssertionErrorsi votre widget ne fonctionne pas comme prévu. Peu importe que vous ayez pris une mesure préalable, car le assertest uniquement destiné à signaler que quelque chose dans votre code est de toute façon incorrect et vous le verrez même si vous appelez super.initStateà la toute fin de votre méthode.

dispose

La disposeméthode est analogue ( source ):

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

Comme vous pouvez le voir, il ne contient également que des assertions qui gèrent la vérification du cycle de vie de débogage . La seconde assertest une bonne astuce car elle garantit que le _debugLifecycleStaten'est modifié qu'en mode débogage (car les assertinstructions ne sont exécutées qu'en mode débogage).
Cela signifie que tant que vous appelez super.dispose quelque part dans votre propre méthode, vous ne perdrez aucune valeur sans que les mixins ajoutent des fonctionnalités supplémentaires.

creativecreatorormaybenot
la source
1
Les documents officiels de Flutter ne sont pas très bons :( merci pour votre réponse :)
CopsOnRoad
Merci pour votre explication, cela vous dérangerait-il également d'expliquer qu'il n'y a qu'une seule ligne de initState()méthode assert(...), alors quel est l'avantage même d'appeler super.initState()dans l'application de production?
CopsOnRoad du
1
Merci beaucoup. Maintenant, c'est logique! Donc, je suppose que pour être sur le côté plus sûr et pour des bonnes pratiques de programmation, il est bon de le garder au début du code.
K Vij
@creativecreatorormaybenot Cela signifie que l'équipe Flutter est hors de leur esprit en mettant mustCallSuperen place cette méthode depuis plus de 2 ans maintenant depuis la naissance de Flutter. Quel est l'avantage de le mettre là, monsieur?
CopsOnRoad du
@creativecreatorormaybenot Même si l'équipe l'a créé pour mixin, il y aura toujours une seule déclaration dans ce initStatequi est assert(...), alors quelle est la signification même d'appeler super.initState()une application de production?
CopsOnRoad du
3

super.initState()devrait toujours être la première ligne de votre initStateméthode.

Depuis les documents:

initState (): Si vous remplacez cela, assurez-vous que votre méthode commence par un appel à super.initState ().

CopsOnRoad
la source
2

Comme vous pouvez le voir dans les classes du framework, vous devez tout faire après l'initialisation du widget, c'est-à-dire après super.initState().

Je cas de disposer serait logiquement dans l'autre sens, tout d'abord faire puis appeler super.dispose().

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

@override
void dispose() {
  // DO STUFF
  super.dispose();
}
Pablo Barrera
la source
THX. Mais je l'ai remarqué dans certains exemples de code. il est appelé à la fin de la méthode initState ...
K Vij
C'est ce que j'ai dit
Pablo Barrera
0

initState est appelé par défaut chaque fois qu'un nouveau widget avec état est ajouté dans une arborescence de widgets. Maintenant, le super.initState effectue l'implémentation par défaut de la classe de base de votre widget.Si vous appelez quelque chose avant super.initState qui dépend de la classe de base, cela pourrait poser problème. C'est pourquoi il est recommandé d'appeler initState de cette façon:

@override
void initState() {
  super.initState();
  // DO STUFF
}
Anirudh Sharma
la source
Le raisonnement est un peu erroné car disposec'est le contraire. Le cadre s'attend à ce que vous appeliez super.dispose à la fin , mais la recommandation est correcte.
creativecreatorormaybenot
Parce que si vous appelez super.dispose avant de supprimer les autres éléments, les composants qui dépendent de votre classe de base peuvent se heurter.
Anirudh Sharma