Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Dart/Flutter have the concept of weak references?

I'm in the early stages of learning Dart & Flutter. I'm looking at how to implement an eventbus, which works fine, but I've noticed that Widgets (and/or their associated state) hold a strong reference to the (global) eventbus, causing a memory leak. The solution is to cancel the subscription in the widget-state's dispose method, but I'd like to know if there's a better approach (I'm coming from Swift which allows variables to be declared as 'weak').

EDIT

I ended up subclassing the state as follows... any better suggestions?

abstract class CustomState<T extends StatefulWidget> extends State {

  List<StreamSubscription> eventSubscriptions = [];

  void subscribeToEvent(Object eventClass, Function callback) {
    StreamSubscription subscription = eventBus.on(eventClass).listen(callback);
    eventSubscriptions.add(subscription);
  }

  void dispose() {
    super.dispose();
    eventSubscriptions.forEach((subscription) => subscription.cancel());
    eventSubscriptions = null;
  }
}

class MyEvent {
  String text;
  MyEvent(this.text);
}

class _MyHomePageState extends CustomState<MyHomePage> {

  @override
  void initState() {
    super.initState();
    subscribeToEvent(MyEvent, onEventFired);
  }

  void onEventFired(event) {
    print('event fired:  ${event.runtimeType}  ${event.text}');
  }
}
like image 963
hunter Avatar asked Apr 14 '18 12:04

hunter


Video Answer


2 Answers

Dart doesn't provide weak reference feature.

An Expando has a weak reference behavior though. Not sure if this is of use in your use case.

  • https://api.dartlang.org/stable/1.24.3/dart-core/Expando-class.html
  • https://groups.google.com/a/dartlang.org/forum/m/#!topic/misc/S7GGxegtJe4
  • What is the Dart "Expando" feature about, what does it do?
    https://github.com/dart-lang/sdk/issues/16172

I sometimes use a Mixin that provides a list where I can add subscriptions and a dispose methode that cancels all subscriptions and add it to widgets and other classes where I need it.

like image 85
Günter Zöchbauer Avatar answered Oct 07 '22 01:10

Günter Zöchbauer


As of 2020, I'd like to add to Günter's answer that I've just published a package that goes as close as possible to a weak-reference by implementing a weak-map and a weak-container, as well as cache functions that take advantage of weak references.

  • https://pub.dev/packages/weak_map

It's much easier to use than an Expando (it uses Expando internally).

like image 34
MarcG Avatar answered Oct 06 '22 23:10

MarcG