回答:
mixin
sのために重要です(そしてあなたのためにもそのため)でライフサイクルメソッドをオーバーライドするときにスーパーメソッドを呼び出すことは、FlutterフレームワークのパラダイムState
です。でも、なぜこれがあるdeactivate
持っているmustCallSuper
注釈を。
さらに、一部mixin
のユーザーは、関数の特定のポイントでこれらのライフサイクルメソッドのスーパーメソッドを呼び出すことを期待しています。
これは、フレームワークのs がこれに該当すると想定しているため、ドキュメントに従ってメソッドsuper.dispose
の最後で呼び出す必要があることを意味します。
たとえば、次のようにしてアサート終わりに:dispose
mixin
State
TickerProviderStateMixin
SingleTickerProviderStateMixin
super.dispose
すべてのティッカーは、super.dispose()を呼び出す前に破棄する必要があります。
別の例:およびでAutomaticKeepAliveMixin
ロジックを実行initState
しdispose
ます。
開始あなたinitState
とsuper.initState
し、あなたを終了するdispose
とsuper.dispose
、追加簡単で安全側になりたい場合はmixin
、あなたに秒State
。
さらに、State
フレームワークはドキュメントで説明されているスーパーメソッドを呼び出すことを想定しているため、他のライフサイクルメソッド(で上書きするメソッド)のドキュメントに従ってください。
したがって、次のことを行う必要があります。
void initState() {
super.initState();
//DO OTHER STUFF
}
ただし、これは本当に重要ではありませんState
。これについては、以下で説明しますが、ミックスインについても同様です。重要なのは、私が見つけたものから判断するアサーションだけです。したがって、本番アプリには影響しません。
State
Pablo BarreraとCopsOnRoadからの前の2つの答えは誤解を招くものだと思います。問題の真実はそれは本当に問題ではなく、遠くを見る必要がないためです。
アクションのみsuper.initState
とsuper.dispose
に取るState
クラスは、それ自体があるアサーションとするのでassert
-statementsのみで評価されているデバッグモード、それが生産モードでは、すなわち、すべてのビルド一度のアプリでは問題ではありません。
以下では、私が何をご案内しますsuper.initState
し、super.dispose
中に行うState
あなたは追加のミックスインを持っていないときに実行されるすべてのコードです。
initState
super.initState
最初に実行されるコードを正確に見てみましょう(ソース):
@protected
@mustCallSuper
void initState() {
assert(_debugLifecycleState == _StateLifecycle.created);
}
ご覧のとおり、ライフサイクルアサーションしかありません。その目的は、ウィジェットが正しく動作することを確認することです。だから、限り、あなたが呼び出すとsuper.initState
、どこか自分自身ではinitState
、次のように表示されますAssertionError
意図したとおりに、あなたのウィジェットが動作しない場合。これはassert
、コード内の何かがとにかく間違っていることを報告するだけsuper.initState
であり、メソッドの最後で呼び出したとしてもそれがわかるため、事前に何らかのアクションをとったかどうかは関係ありません。
dispose
dispose
この方法は、(類似しているソース)。
@protected
@mustCallSuper
void dispose() {
assert(_debugLifecycleState == _StateLifecycle.ready);
assert(() {
_debugLifecycleState = _StateLifecycle.defunct;
return true;
}());
}
ご覧のように、デバッグライフサイクルチェックを処理するアサーションのみが含まれています。ここで2番目assert
は、_debugLifecycleState
デバッグモードでのみ変更されることが保証されるため、素晴らしいトリックです(- assert
ステートメントはデバッグモードでのみ実行されるため)。
つまり、独自のメソッドのsuper.dispose
どこかで呼び出しを行う限り、追加機能を追加するミックスインなしで値を失うことはありません。
initState()
メソッドには1行しかassert(...)
ないのでsuper.initState()
、製品版アプリを呼び出すことの利点は何ですか?
mustCallSuper
、Flutterが誕生してから2年以上の間、その方法を採用することで頭を悩ませています。それをそこに置くことの利点は何ですか?
mixin
に作成した場合でも、これinitState
には1つのステートメントがあります。つまり、本番環境のアプリをassert(...)
呼び出すことの重要性は何super.initState()
ですか?
super.initState()
常にinitState
メソッドの最初の行にする必要があります。
ドキュメントから:
initState():これをオーバーライドする場合は、メソッドが必ずsuper.initState()の呼び出しで始まるようにしてください。
フレームワークのクラスでわかるように、ウィジェットが初期化された後、つまりの後をすべて実行する必要がありますsuper.initState()
。
私が処分する場合は、論理的には逆になりますsuper.dispose()
。最初にすべてを実行してから、を呼び出します。
@override
void initState() {
super.initState();
// DO STUFF
}
@override
void dispose() {
// DO STUFF
super.dispose();
}
initStateは、新しいステートフルウィジェットがウィジェットツリーに追加されるたびにデフォルトで呼び出されます。これで、super.initStateがウィジェットの基本クラスのデフォルト実装を実行します。基本クラスに依存するsuper.initStateの前に何かを呼び出すと、問題が発生する可能性があります。そのため、次の方法でinitStateを呼び出すことをお勧めします。
@override
void initState() {
super.initState();
// DO STUFF
}
dispose
それは反対なので、推論は少し欠陥があります。フレームワークはsuper.dispose
、最後に呼び出すことを期待していますが、推奨事項は正しいです。