hunter
hunter

Reputation: 940

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}');
  }
}

Upvotes: 14

Views: 7023

Answers (4)

user25113247
user25113247

Reputation: 11

I need an iterable WeakHashMap in my project and thus I implemented one using WeakReference and Finalizer classes. Here is the package:

https://pub.dev/packages/weak

Besides the key is WeakReferenced, it has the same attributes and methods as the other Dart HashMap.

Upvotes: 1

Robbendebiene
Robbendebiene

Reputation: 4889

Since dart 2.17 you can use WeakReference.

Any object wrapped in WeakReference(obj) is not kept from being garbage collected.

You access the object via the target property which becomes null when the object got garbage collected.

final myWeakRef = WeakReference(ExampleObj());
// access obj, may be null
print(myWeakRef.target);

Upvotes: 8

Marcelo Glasberg
Marcelo Glasberg

Reputation: 30919

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.

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

Upvotes: 3

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657937

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.

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.

Upvotes: 5

Related Questions