Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 当Get控制器从内存中删除时,如何关闭流?_Flutter_Dart - Fatal编程技术网

Flutter 当Get控制器从内存中删除时,如何关闭流?

Flutter 当Get控制器从内存中删除时,如何关闭流?,flutter,dart,Flutter,Dart,我正在使用以下软件包 我有以下控制器 class GroupController extends GetController{ StreamController<GroupModel> _streamController = BehaviorSubject(); Stream<GroupModel> get stream => _streamController.stream; GroupController(DatabaseService datab

我正在使用以下软件包

我有以下控制器

class GroupController extends GetController{
  StreamController<GroupModel> _streamController = BehaviorSubject();
  Stream<GroupModel> get stream => _streamController.stream;

  GroupController(DatabaseService database, GroupModel group)
  {
   _streamController.addStream(database.groupStream(group));
  }

  @override
  void dispose(){
    print('dispose');
    _streamController.close();
    super.dispose();
  }
}

在尝试关闭控制器时,它会出错。如果在GetController中插入“dispose”,它将被忽略。这是因为disposing是一种用于丢弃StatefulWidget类中的小部件的方法,而不是丢弃控制器的方法,尤其是因为Get会自动智能地丢弃控制器,以便在不再需要时释放资源。如果要关闭流,只要将流插入close方法,Get就会自动关闭流

class GroupController extends GetController{
  StreamController<GroupModel> _streamController = BehaviorSubject();
  Stream<GroupModel> get stream => _streamController.stream;

  GroupController(DatabaseService database, GroupModel group)
  {
   _streamController.addStream(database.groupStream(group));
  }

  @override
  void dispose(){
    print('dispose');
    _streamController.close();
    super.dispose();
  }
}
class GroupController extends GetController{
  StreamController<GroupModel> _streamController = BehaviorSubject();
  Stream<GroupModel> get stream => _streamController.stream;

  GroupController(DatabaseService database, GroupModel group)
  {
   _streamController.addStream(database.groupStream(group));
  }

  // this
  @override
  void close() {
    print('dispose');
    _streamController.close();
    super.close();
  }
}
类GroupController扩展了GetController{
StreamController _StreamController=BehaviorSubject();
Stream get Stream=>\u streamController.Stream;
GroupController(数据库服务数据库,GroupModel组)
{
_streamController.addStream(database.groupStream(group));
}
//这个
@凌驾
无效关闭(){
打印(“处置”);
_streamController.close();
super.close();
}
}
如果您使用的是旧版本的Get,则可以手动使用相同的关闭和关闭方法:

GetBuilder<GroupController>(
        init: GroupController(database, _group),
        dispose:(_)=> Get.find<Controller>().close(), // You do not need this if you are using the latest version
        builder: (GroupController groupController) => StreamBuilder(
          stream: groupController.stream,
          builder: (BuildContext context, AsyncSnapshot<GroupModel> groupSnapshot) {
GetBuilder(
init:GroupController(数据库,_组),
dispose:(\u)=>Get.find().close(),//如果使用的是最新版本,则不需要此选项
生成器:(GroupController GroupController)=>StreamBuilder(
流:groupController.stream,
生成器:(BuildContext上下文,AsyncSnapshot groupSnapshot){

这可能就是您想要的方式。不要在构造函数中添加流,因为这会在控制器重新生成时导致问题。因为它会再次将流添加到构造函数中

import 'dart:async';
import 'package:get/get.dart';
import 'package:rxdart/rxdart.dart';

class GetStreamController<T> extends GetController {
  final Stream<T> Function() value;
  StreamController<T> _streamController = BehaviorSubject();
  StreamSubscription _streamSubscription;
  Stream<T> get stream => _streamController.stream;

  GetStreamController(this.value);
  @override
  void onInit()
  {
    super.onInit();
    _streamSubscription = value().listen((event) {
      _streamController.add(event);
    });
  }

  @override
  void onClose()
  {
    super.onClose();
    _streamSubscription.cancel();
    _streamController.close();
  }
}
导入'dart:async';
导入“package:get/get.dart”;
导入“包:rxdart/rxdart.dart”;
类GetStreamController扩展了GetController{
最终流函数()值;
StreamController _StreamController=BehaviorSubject();
StreamSubscription\u StreamSubscription;
Stream get Stream=>\u streamController.Stream;
GetStreamController(此.value);
@凌驾
void onInit()
{
super.onInit();
_streamSubscription=value()。侦听((事件){
_streamController.add(事件);
});
}
@凌驾
void onClose()
{
super.onClose();
_streamSubscription.cancel();
_streamController.close();
}
}

您希望何时调用
dispose
方法?当小部件从内存中删除时,但我希望它发生在小部件从树中删除时。但一般来说,我只想知道如何利用GetBuilder的dispose属性。在Dart中没有可以放置在类上的侦听器,当对象从内存中删除。widgets中的
dispose
方法用于从widget树中删除对象。那么,如何使用get关闭流?如何利用GetBuilder的dispose属性?如果传递statefull widget的dispose方法,如何引用控制器?简单回答?您不能。widgetget包中的属性不公开清理代码的
dispose
属性,因此您无法轻松完成想要完成的任务。但是出于好奇,为什么要使用get而不是类似于provider的东西?太好了,我显然需要更新我的get。我尝试使用close方法关闭流,但出现以下错误
I/flatter(23404):如果调用close,则记录I/flatter(23404):close不能被称为I/flatter(23404):[GET]GroupController已从内存中删除
,因此它确实调用了该方法,但随后记录无法调用关闭?我在回答的底部添加了用于控制器的代码。我做错了什么?啊,好吧,因此需要先排空流。因此,我必须实现一个未来,排空流,然后关闭控制器。否我不确定这有多安全。我添加了下面的工作代码,但接受了您的回答,因为我想找到关闭回调。这是因为您没有使用本地流,您已将现有流添加到本地流,因此您需要先排空流。日志显示一个一般错误,因为Get有一个try-catch,并且引发了任何错误在close方法中,它抛出了相同的异常,但实际上正在调用close,但是流有一个错误,因为它没有被排空,并且这个错误触发了Get的捕获(e)。如果没有_streamController.addStream(database.groupStream(group));此附加过程是不必要的。您的代码是100%安全的OK,因此现在我有以下问题。我的第二个GetBuilder在尝试关闭流的小部件树中删除它时调用close方法。实际上,我在github页面上发布了这篇文章,因为我不确定如何将流与我想要的控制器一起使用尽管问题在上次更新中得到了解决,但这是一个错误,使得任何GetBuilder都可以调用主GetBuilder设备。感谢您报告此错误,它正在清除测试,并且添加了具有关闭子页面流的测试。我也更新了代码,因为在constructor.Bec中分配流时遇到了问题因为每次重建都会调用构造函数。但是initState不会!
GetBuilder<GroupController>(
        init: GroupController(database, _group),
        dispose:(_)=> Get.find<Controller>().close(), // You do not need this if you are using the latest version
        builder: (GroupController groupController) => StreamBuilder(
          stream: groupController.stream,
          builder: (BuildContext context, AsyncSnapshot<GroupModel> groupSnapshot) {
import 'dart:async';
import 'package:get/get.dart';
import 'package:rxdart/rxdart.dart';

class GetStreamController<T> extends GetController {
  final Stream<T> Function() value;
  StreamController<T> _streamController = BehaviorSubject();
  StreamSubscription _streamSubscription;
  Stream<T> get stream => _streamController.stream;

  GetStreamController(this.value);
  @override
  void onInit()
  {
    super.onInit();
    _streamSubscription = value().listen((event) {
      _streamController.add(event);
    });
  }

  @override
  void onClose()
  {
    super.onClose();
    _streamSubscription.cancel();
    _streamController.close();
  }
}