当处理程序需要 BuildContext 时,避免内存泄漏的最佳方法是什么?

pol*_*a-c 5 memory-leaks dart flutter

我喜欢 Dart 和 Flutter,垃圾收集 (GC) 的工作效率高达 99%。然而,在某些情况下,GC 无法识别某个对象将不再被使用。

我听说将上下文传递给闭包有时可能会导致严重的内存泄漏。我应该始终避免它还是在某些情况下可以?就我而言,我需要显示对话框。这是我看到的选项:

  1. 具有存储上下文的闭包的无状态小部件:
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MyCoolButton(
      onTap: () async {
        unawaited(
          showDialog(
            context: context,
            builder: (context) => MyDialog(),
          ),
        );
      },        
    );
  }
}
Run Code Online (Sandbox Code Playgroud)
  1. 带有成员处理程序的有状态小部件:
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,        
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*cer 1

我知道将上下文传递给闭包可能会导致严重的内存泄漏。

这是一个误解。

您应该始终避免保存/缓存,BuildContext因为这可能会导致上下文在需要时分离的情况。传递上下文是很常见的。假设您构建了一个Widget以 a作为参数的构建器,则将使用s方法WidgetBuilder的上下文调用该构建器函数/闭包。传递上下文是不可避免的,但也不是问题。WidgetbuildshowDialog

一般来说,在我工作的代码库中,禁止将构建上下文传递给构造函数。始终首选传递构建上下文用于访问的内容。