当我的Get Controller从内存中删除时,我如何关闭一个流?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当我的Get Controller从内存中删除时,我如何关闭一个流?相关的知识,希望对你有一定的参考价值。

我使用的是以下软件包 https:/pub.devpackagesget .

我有以下控制器

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();
  

但是当我叫它的时候,从来没有叫过dispose。我是这样叫的

GetBuilder<GroupController>(
        init: GroupController(database, _group),
        builder: (GroupController groupController) => StreamBuilder(
          stream: groupController.stream,
          builder: (BuildContext context, AsyncSnapshot<GroupModel> groupSnapshot) 

我希望每当控制器从内存中移除时,控制器的dispose方法就被调用。

我注意到GetBuilder有一个dispose回调。而且它需要一个widget的状态。那么我是否需要让持有控制器的widget状态为满?还是我需要传递一个新的statefull widget来保持状态?文档中对此并不十分清楚。我如何在控制器上调用dispose?

我注意到每当控制器从内存中删除时,都会有一个控制台日志,难道没有一个回调,所以我可以在那里关闭流吗?我真的很想避免让widget变成满状态。

编辑

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 close()
    print('log if close is invoked');
    _streamController.close();
    super.close();
  

生成以下日志

I/flutter (23404): log if close is invoked 
I/flutter (23404): Close can't be called 
I/flutter (23404): [GET] GroupController deleted from memory

不知何故,当试图关闭控制器时,它会出错。

答案

如果你在你的GetController中插入一个 "dispose",它将被忽略。这是因为disposing是StatefulWidget类中丢弃widget的方法,而不是丢弃控制器的方法,尤其是因为当不再需要控制器时,Get会自动和智能地丢弃控制器以释放资源。如果你想关闭流,只要你把你的流插入到关闭方法中,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));
  

  // this
  @override
  void close() 
    print('dispose');
    _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) 
另一答案

这可能是你想要的方式。不在contructor中添加流,因为这会导致控制器get的重建时出现问题。因为它会把流再一次添加到contructor中。

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();
  

以上是关于当我的Get Controller从内存中删除时,我如何关闭一个流?的主要内容,如果未能解决你的问题,请参考以下文章

从 NSUserDefaults 中删除数组时的内存问题

当我尝试从单链表中删除节点时,为啥我的 C 程序会崩溃

重定向到`Java`中的get方法时如何从url中删除参数[重复]

如何在Controller Java Spring中使用不同的GET方法

如何从浏览器中删除统一堆内存?

UITableView 内存问题