Код-ревью Middle Жизненный цикл обновлено
Код-ревью: утечки контроллеров и подписок
Вопрос
Экран поиска. Найдите проблемы жизненного цикла.
class _SearchState extends State<Search> {
final _controller = TextEditingController();
late AnimationController _anim;
StreamSubscription? _sub;
@override
void initState() {
_anim = AnimationController(vsync: this, duration: const Duration(milliseconds: 200));
_sub = widget.repo.results.listen((r) => setState(() => _results = r));
final locale = Localizations.localeOf(context);
super.initState();
}
@override
Widget build(BuildContext context) {
final focus = FocusNode();
return TextField(controller: _controller, focusNode: focus);
}
@override
void dispose() {
super.dispose();
_anim.dispose();
}
}
Коротко
Правила: super.initState() первой строкой, super.dispose() последней. Всё, что создано в State (контроллеры, FocusNode, подписки), создаётся в initState и освобождается в dispose.
Что должен найти ревьюер
- Стильстрока 11
super.initState()должен быть первой строкойinitState. - Ошибкастрока 10
Localizations.localeOf(context)вinitState: подписка наInheritedWidgetздесь запрещена, перенести вdidChangeDependencies. - Ошибкастрока 9В колбэке подписки нет проверки
mounted, а подписка не отменяется вdispose: утечка иsetStateпослеdispose. - Ошибкастрока 16
FocusNodeсоздаётся вbuildна каждом перестроении и никогда не освобождается: утечка и потеря фокуса. Создать вinitState, освободить вdispose. - Ошибкастрока 23
_controller.dispose()не вызван,_sub?.cancel()нет. - Стильстрока 22
super.dispose()должен быть последней строкой: сначала освобождаем свои ресурсы. - Ошибкастрока 1Для
vsync: thisнужен миксинSingleTickerProviderStateMixin, иначе код не скомпилируется.
Разбор
Правила: super.initState() первой строкой, super.dispose() последней. Всё, что создано в State (контроллеры, FocusNode, подписки), создаётся в initState и освобождается в dispose. Ничего долгоживущего не создаётся в build. InheritedWidget читается в didChangeDependencies или build.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.