代码之家  ›  专栏  ›  技术社区  ›  boeledi

颤振-继承小部件-释放

  •  3
  • boeledi  · 技术社区  · 6 年前

    我想知道是否有人知道何时处理继承的小部件?

    这个问题的原因是,我正在做一些实验,并使用一个继承的小部件作为一个BLoC的提供者。 这个BLoC在InheritedWidget级别初始化,并使用StreamController。

    由于不建议关闭StreamController,我正在尝试寻找解决方案。

    这里有一段代码(愚蠢的代码只是为了实验)来说明这个问题:

    ///
    /// ApplicationProvider
    /// 
    /// A provider of ApplicationBloc
    /// 
    class ApplicationProvider extends InheritedWidget {
      //
      // Initialization of the BLoC
      //
      final ApplicationBloc bloc = new ApplicationBloc();
    
      ApplicationProvider({Key key, Widget child}) : super(key: key, child: child);
    
      @override
      bool updateShouldNotify(_) => true;
    
      static ApplicationBloc of(BuildContext context, [bool redraw = true]) {
        return redraw ? (context.inheritFromWidgetOfExactType(ApplicationProvider) as ApplicationProvider).bloc
                      : (context.ancestorWidgetOfExactType(ApplicationProvider) as ApplicationProvider).bloc;
      }
    }
    
    //
    // The BLoC
    //   
    class ApplicationBloc {
    
      int _counter;
      StreamController<int> _counterController = new StreamController<int>.broadcast();
      Sink get inCounter => _counterController;
    
      Stream<int> get outCounter => _counterController.stream;
    
      ApplicationBloc(){
        _counter = 0;
      }
    
      void increment(){
        _counter++;
        inCounter.add(_counter);
      }
    
      int get counter => _counter;
    
      //
      // How could I call this method ???
      //
      void dispose(){
        _counterController.close();
      }
    }
    

    所以主要的问题是 如何调用BLoC的dispose()方法 " ?

    非常感谢你的帮助。

    2 回复  |  直到 6 年前
        1
  •  13
  •   Rémi Rousselet    6 年前

    InheritedWidget 行为与其他人相同 Widget 去吧。 他们的寿命很短:通常不超过一岁 build 打电话来。

    如果你想存储更长时间的数据, 继承的小部件 不是你想要的。你需要一个 State 为了这个。

    这也意味着最终,你可以使用 国家 是你的集团处置。

    class BlocHolder extends StatefulWidget {
      final Widget child;
    
      BlocHolder({this.child});
    
      @override
      _BlocHolderState createState() => _BlocHolderState();
    }
    
    class _BlocHolderState extends State<BlocHolder> {
      final _bloc = new MyBloc();
    
      @override
      Widget build(BuildContext context) {
        return MyInherited(bloc: _bloc, child: widget.child,);
      }
    
    
      @override
      void dispose() {
        _bloc.dispose();
        super.dispose();
      }
    }
    
    class MyInherited extends InheritedWidget {
      final MyBloc bloc;
    
      MyInherited({this.bloc, Widget child}): super(child: child);
    
      @override
      bool updateShouldNotify(InheritedWidget oldWidget) {
        return oldWidget != this;
      }
    }
    
    
    class MyBloc {
      void dispose() {
    
      }
    }
    
        2
  •  0
  •   boformer    6 年前

    继承的小部件的行为非常类似于无状态的小部件,它也没有 dispose 方法。继承的小部件经常被重新构建,存储在其中的所有值都将丢失(如果没有适当的 updateShouldNotify 实现时,依赖的小部件树也将频繁地重建!).

    要解决这个问题,可以使用 StatefulWidget :

    import 'dart:async';
    
    import 'package:flutter/widgets.dart';
    
    class ApplicationProvider extends StatefulWidget {
      const ApplicationProvider({Key key, this.child}) : super(key: key);
    
      final Widget child;
    
      @override
      State<StatefulWidget> createState() => _ApplicationProviderState();
    }
    
    class _ApplicationProviderState extends State<ApplicationProvider> {
      final ApplicationBloc bloc = new ApplicationBloc();
    
      @override
      void dispose() {
        bloc.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return _ApplicationProvider(
          bloc: bloc,
          child: widget.child,
        );
      }
    }
    
    class _ApplicationProvider extends InheritedWidget {
      _ApplicationProvider({
        Key key,
        this.bloc,
        Widget child,
      }) : super(key: key, child: child);
    
      final ApplicationBloc bloc;
    
      @override
      bool updateShouldNotify(_ApplicationProvider oldWidget) {
        return bloc != oldWidget.bloc;
      }
    }
    
    class ApplicationBloc {
      ApplicationBloc of(BuildContext context) {
        final _ApplicationProvider provider = context.inheritFromWidgetOfExactType(_ApplicationProvider);
        return provider.bloc;
      }
    
      int _counter;
      StreamController<int> _counterController = new StreamController<int>.broadcast();
      Sink get inCounter => _counterController;
    
      Stream<int> get outCounter => _counterController.stream;
    
      ApplicationBloc() {
        _counter = 0;
      }
    
      void increment() {
        _counter++;
        inCounter.add(_counter);
      }
    
      int get counter => _counter;
    
      void dispose() {
        _counterController.close();
      }
    }