Home > database >  What is the best way to avoid memory leaks when a handler needs BuildContext?
What is the best way to avoid memory leaks when a handler needs BuildContext?

Time:09-28

I know passing context to closure sometimes may cause a serious memory leak. Should i always avoid it or there are cases when it is ok? In my case I need to show dialog. Here is the options I see:

  1. Stateless widget with closure that stores context:
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MyCoolButton(
      onTap: () async {
        unawaited(
          showDialog(
            context: context,
            builder: (context) => MyDialog(),
          ),
        );
      },        
    );
  }
}
  1. Stateful widget with a member-handler:
class MyWidget extends StatefulWidget {
  const MyWidget({Key? key}) : super(key: key);

  @override
  State<SecondaryControls> createState() => _SecondaryControlsState();
}

class _MyWidgetState extends State<MyWidget> {

  void _openDialog() async {
    await showDialog(
      context: context,
      builder: (context) => MyDialog(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MyCoolButton(
        onTap: _openDialog,        
    );
  }
}

CodePudding user response:

I know passing context to closure can cause a serious memory leak.

This is a misunderstanding.

You should always avoid saving/caching BuildContext as it might cause a situation where the context is detached at the time it is needed. Passing a context is pretty common. Say you build a Widget that takes in a WidgetBuilder as a parameter, that builder function/closure will be called with the context from the Widgets build method. Passing in a context into showDialog is unavoidable but also not an issue.

Generally, in code bases I work in, it's forbidden to pass a build context to a constructor. It is always preferred to pass in the thing the build context is used to access.

CodePudding user response:

There is nothing wrong with passing a BuildContext to functions in this manner, otherwise showDialog wouldn't have been designed like that.

There is also no such thing as a memory leak in Dart, the garbage collector can handle closures and circular references just fine.

  • Related