Devo ligar para super.initState no final ou no começo?

10

Estou confuso a respeito de onde chamar a super.initSate()vibração? Em alguns exemplos de código, é chamado no início e em outros no final. Existe alguma diferença?

Tentei pesquisar no google, mas não encontrei nenhuma explicação sobre a posição dessa chamada de função.

Qual deles está correto?

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

ou

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

Respostas:

4

Importa para mixins (e por isso também para você )

É um paradigma na estrutura do Flutter chamar o super método ao substituir os métodos do ciclo de vida em a State. É por isso que ainda deactivatetem uma mustCallSuperanotação .
Além disso , alguns mixinesperam que você chame os super métodos desses métodos de ciclo de vida em um ponto específico da função.

Isso significa que você deve seguir a documentação e chamada super.dispose no final do seu disposemétodo porque mixins sobre Stateno quadro esperar que este é o caso.
Por exemplo: TickerProviderStateMixine afirme no final:SingleTickerProviderStateMixin super.dispose

Todos os Tickers devem [...] ser descartados antes de chamar super.dispose ().

Outro exemplo: AutomaticKeepAliveMixinexecuta a lógica em initStatee dispose.

Conclusão

Comece initStatecomsuper.initState e termine disposecomsuper.dispose se quiser estar do lado fácil e seguro, adicionando mixins ao seu State.
Além disso, siga a documentação para outros métodos de ciclo de vida (qualquer método em que você substitua State) porque a estrutura espera que você chame os super métodos, conforme descrito na documentação.

Assim, o seguinte é o que você deve fazer:

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

No entanto, isso realmente não importa State, o que explicarei a seguir e mesmo para mixins, importa apenas para afirmações que julgam o que eu poderia encontrar - para que não afetasse seu aplicativo de produção.

Não importa para State

Penso que as duas respostas anteriores de Pablo Barrera e CopsOnRoad são enganosas, porque a verdade é que isso realmente não importa e você não precisa procurar muito.

As únicas ações que super.initStatee executadas super.disposena Stateprópria classe são asserções e como as assertdeclarações são avaliadas apenas no modo de depuração , isso não importa de todo quando você cria o aplicativo, ou seja, no modo de produção.


A seguir, orientarei você sobre o que fazer super.initStatee o que é, todo o código que será executado quando você não tiver mixins adicionais.super.disposeState

initState

Vejamos exatamente qual código é executado super.initStateprimeiro ( fonte ):

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

Como você pode ver, existe apenas uma asserção de ciclo de vida e o objetivo é garantir que seu widget funcione corretamente. Então, enquanto você chama super.initState em algum lugar em seu próprio initState, você verá um AssertionError, se o seu widget não está funcionando como deveria. Não importa se você tomou alguma ação anterior, pois o assertobjetivo é apenas informar que alguma coisa no seu código está errada e você verá isso mesmo se chamar super.initStateno final do seu método.

dispose

O disposemétodo é análogo ( fonte ):

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

Como você pode ver, ele também contém apenas asserções que lidam com a verificação do ciclo de vida da depuração . O segundo assertaqui é um bom truque, pois garante que _debugLifecycleStateapenas seja alterado no modo de depuração (pois as assertinstruções são executadas apenas no modo de depuração).
Isso significa que, desde que você chame em super.dispose algum lugar no seu próprio método, você não perderá nenhum valor sem os mixins adicionarem funcionalidade adicional.

creativecreatorormaybenot
fonte
11
Os documentos oficiais do Flutter não são muito bons :( obrigado por sua resposta :)
CopsOnRoad
Obrigado pela sua explicação, você também se importaria de explicar? Existe apenas uma linha no initState()método assert(...), então qual é o benefício de chamar o super.initState()aplicativo de produção?
CopsOnRoad 15/10/19
11
Muito obrigado. Agora faz sentido! Então, acho que por um lado mais seguro, e por boas práticas de programação, é bom mantê-lo no início do código.
K Vij
@creativecreatorormaybenot Isso significa que a equipe do Flutter está maluca, adotando mustCallSuperesse método há mais de dois anos desde que o Flutter passou a existir. Qual é o benefício de colocá-lo lá, senhor?
CopsOnRoad 15/10/19
@creativecreatorormaybenot Mesmo que a equipe tenha criado para isso mixin, ainda haverá uma única declaração, initStateou seja assert(...), qual é o significado de chamar super.initState()um aplicativo de produção?
CopsOnRoad 15/10/19
3

super.initState()deve sempre ser a primeira linha do seu initStatemétodo.

Dos documentos:

initState (): se você substituir isso, verifique se o seu método começa com uma chamada para super.initState ().

CopsOnRoad
fonte
2

Como você pode ver nas classes da estrutura, você deve fazer tudo depois que o widget for inicializado, ou seja, depois super.initState().

O caso de descartar seria logicamente de outra maneira, primeiro faça tudo e depois ligue super.dispose().

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

@override
void dispose() {
  // DO STUFF
  super.dispose();
}
Pablo Barrera
fonte
Valeu. Mas notei isso em alguns exemplos de código. ele é chamado no final do método initState ...
K Vij
Foi o que eu disse #
Pablo Barrera
0

O initState é chamado por padrão sempre que um novo widget com estado é adicionado a uma árvore de widgets. Agora, o super.initState executa a implementação padrão da classe base do seu widget. Se você chamar qualquer coisa antes do super.initState que depende da classe base, isso poderá causar problemas. É por isso que é recomendável que você chame initState desta maneira:

@override
void initState() {
  super.initState();
  // DO STUFF
}
Anirudh Sharma
fonte
O raciocínio é um pouco falho, porque disposeé o contrário. A estrutura espera que você ligue super.dispose no final , mas a recomendação está correta.
Creativecreatorormaybenot
Porque se você chamar super.dispose antes de descartar as outras coisas, os componentes que dependem da sua classe base podem colidir.
Anirudh Sharma