Flutter - 关闭小部件时 BLoC 流实例会导致内存泄漏吗?

Posted

技术标签:

【中文标题】Flutter - 关闭小部件时 BLoC 流实例会导致内存泄漏吗?【英文标题】:Flutter - Will BLoC stream instances cause memory leak when a widget is closed? 【发布时间】:2019-04-22 19:18:26 【问题描述】:

在某些情况下,经常创建和关闭带有各自 BLoC 的屏幕。所以我有点担心在这个过程中创建的 Streams 实例的内存安全,因为它们似乎没有被放置在某个地方或者它们是否是 GC-ed。这显然取决于 DART 库和颤振的具体实现。所以如果你知道他们的行为,请告诉我。

这些是我遇到的一些场景。

    类似浏览器的多标签应用程序。 浏览屏幕。 (但它并没有那么有害。) 当对话框中有 BLoC 时,showDialog() 情景。这是一个更为常见的情景。应用中可能会频繁弹出大量对话框。

我想知道是否有必要重写 dispose() 函数并显式关闭 BLoCProvider 中的所有流。似乎现有的教程没有提到它。

【问题讨论】:

【参考方案1】:

只要不再使用流,就会正确清理它们。 问题是,仅仅删除变量并不足以确定它是否未被使用。它仍然可以在后台运行。

您需要调用Sink.close() 以便它停止关联的StreamController,以确保稍后可以由GC 释放资源。

为此,您必须使用StatefulWidget.dispose 方法:

abstract class MyBloc 
  Sink foo;
  Sink bar;


class MyWiget extends StatefulWidget 
  @override
  _MyWigetState createState() => _MyWigetState();


class _MyWigetState extends State<MyWiget> 
  MyBloc bloc;

  @override
  void dispose() 
    bloc.bar.close();
    bloc.foo.close();
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    // ...
  

【讨论】:

你认为通过接口访问块总是比使用有效使用继承小部件的提供者更好吗? @stt106 你什么意思?接口不替代提供者,提供者也不替代接口 会在 slack 上和你聊天。 你需要一个 Inheritedwidget 和一个 StatefulWidget @rxlky 你会想要使用rxdartBehaviorSubject

以上是关于Flutter - 关闭小部件时 BLoC 流实例会导致内存泄漏吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 小部件测试中等待未来完成?

BLoC 和多个流 - 有更好的解决方案吗?

在 Flutter 中使用 BLoC - 在有状态小部件与无状态小部件中的使用

Flutter 状态管理(BloC):无状态与有状态小部件

Flutter - 使用依赖注入时何时关闭流

从非小部件类访问 Flutter Bloc