Ответ
Оба метода являются частью жизненного цикла объекта State в Flutter, но вызываются в принципиально разных сценариях.
deactivate()
- Когда вызывается: Когда виджет, связанный с этим
State, удаляется из дерева виджетов, но фреймворк может позже вставить его обратно в это же или другое место. - Типичный сценарий: Перемещение виджета с
GlobalKeyв другую часть дерева. Flutter оптимизирует производительность, сохраняяState. - Что здесь делать: Временная приостановка активности (например, пауза анимации или таймера), но не окончательное освобождение ресурсов.
dispose()
- Когда вызывается: Когда объект
Stateудаляется навсегда и больше никогда не будет использован. Это финальная точка жизненного цикла. - Типичный сценарий: Закрытие экрана (страницы), удаление виджета без
GlobalKey. - Что здесь делать (обязательно): Освобождение всех занятых ресурсов для предотвращения утечек памяти:
- Закрытие
StreamControllerи отписка отStreamSubscription. - Вызов
.dispose()уAnimationController,TextEditingController,ScrollController. - Закрытие открытых файловых дескрипторов или сетевых соединений.
- Закрытие
Пример:
class _MyWidgetState extends State<MyWidget> {
late StreamSubscription<int> _subscription;
late AnimationController _animationController;
@override
void initState() {
super.initState();
_subscription = myStream.listen((data) { /* ... */ });
_animationController = AnimationController(vsync: this);
}
@override
void deactivate() {
// Виджет временно скрыли. Можно приостановить анимацию.
_animationController.stop();
super.deactivate();
}
@override
void dispose() {
// Виджет уничтожается. Освобождаем ресурсы.
_subscription.cancel(); // Критически важно!
_animationController.dispose(); // Критически важно!
super.dispose();
}
}
Итог: deactivate — это «пауза», dispose — это «окончательное удаление». Все тяжелые ресурсы освобождаются только в dispose().