Flutter – Dispose of resources and monitor number of instances of resources

Issue

I need some reassurance that I am not creating new objects without disposing of them, or need to know how I can manually monitor and dispose of them. I thought Navigator.pop() should dispose of my resources such as flutter-bloc cubits/blocs but it doesn’t seem like it does.

I provide a cubit for a named route by using onGenerateRoute like so:

in onGenerateRoute:

  case Routes.LOGGED_OUT_NICKNAME:
    page = MyCustomRouteTransitionAnimation<LoggedOutNickNameView>(
      builder: (context) => BlocProvider.value(
          value: LoggedOutNickNameCubit(
              SaveNickNameLocallyUseCase(), GetUserFieldFromLocalUseCase()),
          child: LoggedOutNickNameView()),
    );
    break;

I have noticed that when I navigate to the route, it creates the cubit each time, which is great, but when I Navigator.pop(), the cubit does not get closed.

enter image description here

When I monitor the memory in dart devtools, it seems to always show 2 instances of my cubit no matter what, so seems kind of useless. Am I reading that wrong?:

enter image description here

How can I get the actual number of instances of objects in memory from dart devtools, and how can I ensure I am clearing resources appropriately, especially blocs/cubits?

Solution

Your code has a problem. The bloc is created but no one is disposing it. That’s why you don’t see the closing (suppose you have such a print statement in the close method of the bloc) message in the console. Value constructor (BlocProvider.value) should be used only in cases when you want to manage the lifetime of the bloc manually. It means that you are to create it when you need and you are to dispose when you don’t. Your code has no (or you haven’t provided full code) bloc disposing statements. If you want bloc to dispose itself automatically you should use BlocProvider constructor like that:

builder: (context) => BlocProvider(
          create: (context) => LoggedOutNickNameCubit(
              SaveNickNameLocallyUseCase(), GetUserFieldFromLocalUseCase()),
          child: LoggedOutNickNameView()),

In that case, if you leave the page with Navigator.pop method you should see the closing message in your console.
It’s absolutely wrong to create a bloc instance in the build method like this. The build method can be invoked many times so that your bloc will be recreated many times as well. And, usually, it’s not the behavior we need.

The memory monitor shows how many instances in memory are available in the time of the snapshot. It shows 2 instances of the bloc, because, as I said earlier, your build method is wrong: it creates a new instance of the bloc on every invocation (and at the time of the snapshot your widget has been rebuilt at least 2 times). And usually, it’s the right (actual) number (assuming that dev tools have no bugs). But you should be aware of the fact that memory snapshot is not live, i.e. it doesn’t change the number of instances in real-time. So if you need to see another number you are to create a new snapshot later. And be carefully observing the results of a new snapshot, because the old one is kept there, and it’s easy to look into the wrong one. It looks like that this is the problem.

Answered By – ChessMax

Answer Checked By – Jay B. (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.