Provider를 이용한 MVVM구조로 개발하면서, ViewModel의 상태변수 중 하나로 StreamSubscription을 관리할 상황이 왔다.
void dispose() {
Provider.of<ViewModel>(context, listen: false).disposeAll();
super.dispose();
}
처음에는 dispose를 위와 같이 View의 dispose에서 구현했지만, 아래와 같은 예외가 발생했다.
FlutterError (Looking up a deactivated widget's ancestor is unsafe.
At this point the state of the widget's element tree is no longer stable.
To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.)
dispose가 호출될 때는 해당 위젯이 이미 위젯 트리에서 제거되는 중이라 context를 안전하게 쓸 수 없기 때문에 발생한 예외이다.
Provider로 ViewModel에 ChangeNotifier를 확장해서 사용한다면, 기본적으로 dispose를 override해서 사용할 수 있다.
아래와 같이 ViewModel내부에서 dispose를 구현한다면, 관리 해야하는 StreamSubscription과 같은 구독을 View까지 가지 않고 내부에서 해결할 수 있다.
class ViewModel extends ChangeNotifier {
StreamSubscription? mySubscription;
...
void dispose() {
if (mySubscription != null) {
mySubscription!.cancel();
}
super.dispose();
}
}