在 dispose 方法中访问 BlocProvider.of<Bloc>(context)

Posted

技术标签:

【中文标题】在 dispose 方法中访问 BlocProvider.of<Bloc>(context)【英文标题】:access BlocProvider.of<Bloc>(context) in dispose method 【发布时间】:2020-02-16 06:26:43 【问题描述】:

有人知道我该怎么做吗?

我的代码:

  @override
  void dispose() 
    final FiltersBloc filtersBloc = 
       BlocProvider.of<FiltersBloc>(context);
    super.dispose();
  

错误是:

flutter:         BlocProvider.of() called with a context that does not contain a Bloc of type FiltersBloc.
flutter:         No ancestor could be found starting from the context that was passed to
flutter: BlocProvider.of<FiltersBloc>().
flutter:
flutter:         This can happen if:
flutter:         1. The context you used comes from a widget above the BlocProvider.
flutter:         2. You used MultiBlocProvider and didn't explicity provide the BlocProvider types.
flutter:
flutter:         Good: BlocProvider<FiltersBloc>(builder: (context) => FiltersBloc())
flutter:         Bad: BlocProvider(builder: (context) => FiltersBloc()).
flutter:
flutter:         The context used was: FiltersDrawer(dirty, state: _FiltersDrawerState#86e8a)

另外,如果我按照错误代码改用final filtersBloc = BlocProvider&lt;FiltersBloc&gt;(builder: (context) =&gt; FiltersBloc()),我将无法再调用filtersBloc.dispatch()

我知道对于 initState,我们可以改为 didChangeDependencies。但我找不到 dispose 的等价物。

任何帮助将不胜感激。谢谢!

【问题讨论】:

你好,魏。为什么你需要让 Bloc 内部处置?你想在这里处理 Bloc 对象吗? 不,我想在处理小部件时向我的集团分派一个事件 如何在父窗口小部件中声明final FiltersBloc filtersBloc = BlocProvider.of&lt;FiltersBloc&gt;(context);,然后将其作为参数传递,以便在处理时可以使用widget.filtersBloc.dispatch(); 谢谢,我从这里得到了答案:github.com/felangel/bloc/issues/588。基本上就是你说的。谢谢 【参考方案1】:

BlockProvider 需要初始化上下文。你可以在屏幕的Widget build()上初始化它

late FiltersBloc filtersBloc;

@override
Widget build(BuildContext context)
  filtersBloc = BlocProvider.of<FiltersBloc>(context);
  return ...

...然后在dispose()上调用所需的方法

@override
void dispose() 
  filtersBloc.dispatch();
  super.dispose();

【讨论】:

您应该指出late 仅适用于null safety 的项目。【参考方案2】:

一个更详细的小方法:

听起来很安全,您可以使用@Omatt 回答。

不健全的 null 安全性,您可以使用以下方法:

在类中声明一个静态变量,并在initbuild中赋值如下:

class MyAwesomeWidget extends StatefulWidget 
  const MyAwesomeWidget(
    Key key,
  );

  @override
  _MyAwesomeWidgetState createState() => _MyAwesomeWidgetState();


class _MyAwesomeWidgetState extends State<MyAwesomeWidget> 
  FiltersBloc filtersBloc;

  @override
  void initState() 
    super.initState();
    new Future.delayed(Duration.zero, () 
      filterBloc = BlocProvider.of<FiltersBloc>(context);
    );
  

  @override
  void dispose() 
    filterBloc.myFunction();
    super.dispose();
  


【讨论】:

以上是关于在 dispose 方法中访问 BlocProvider.of<Bloc>(context)的主要内容,如果未能解决你的问题,请参考以下文章

在 Flutter 中,方法 'dispose' 被调用为 null

在 Form.Dispose() 方法中安全调用

Dispose() 用于清理托管资源?

析构函数、dispose 和 finalize 方法的区别

编写高质量代码改善C#程序的157个建议——建议49:在Dispose模式中应提取一个受保护的虚方法

RxJava2 中多种取消订阅 dispose 的方法梳理( 源码分析 )