SchedulerBinding.instance.schedulerPhaseを使う
Fri Dec 29 2023
例えば ChangeNotifier.notifyListeners
を呼んでも良いタイミングかどうか知りたい時がある。もしビルド中に通知して、リスナーの1人が State.setState
を呼んだりするとエラーになってしまう。アプリケーションのコードを書いているときにこんなケースが出てくることはあまりないだろうが、パッケージなんかを作っていると稀に遭遇する。そんな時に使えるのが SchedulerBinding.schedulerPhase
。
schedulerPhase
はプロダクションコードにも使って大丈夫なのだろうかと心配になるかもしれない。どう見ても正攻法とは思えないから。実際、デバッグビルドでしか使えない関数がある。でも schedulePhase
は NavigatorState
のコード内でも使用されているので全然問題なさそう。以下は NavigatorState._handleHistoryChanged
メソッドからの抜粋(3488行目)。 NavigationNotification
の通知タイミングを遅らせるかどうかを現在の schedulePhase
を元に判断している。
// Avoid dispatching a notification in the middle of a build. switch (SchedulerBinding.instance.schedulerPhase) { case SchedulerPhase.postFrameCallbacks: notification.dispatch(context); case SchedulerPhase.idle: case SchedulerPhase.midFrameMicrotasks: case SchedulerPhase.persistentCallbacks: case SchedulerPhase.transientCallbacks: SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) { if (!mounted) { return; } notification.dispatch(context); }); }