Dart/Flutter 有弱引用的概念吗?

问题描述 投票:0回答:4

我正处于学习DartFlutter的早期阶段。我正在研究如何实现 eventbus,它工作得很好,但我注意到 Widget(和/或其关联状态)持有对(全局)事件总线的强引用,导致内存泄漏。解决方案是取消 widget-state 的 dispose 方法中的订阅,但我想知道是否有更好的方法(我来自 Swift,它允许将变量声明为“弱”)。

编辑

我最终对状态进行了子类化,如下...还有更好的建议吗?

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}');
  }
}
memory-leaks dart flutter weak-references circular-reference
4个回答
6
投票

Dart 不提供弱引用功能。

虽然 Expando 具有弱引用行为。 不确定这是否适用于您的用例。

我有时使用 Mixin,它提供了一个列表,我可以在其中添加订阅,以及一个 dispose 方法,该方法取消所有订阅并将其添加到小部件和其他我需要的类中。


6
投票

自 dart 2.17 起,您可以使用 WeakReference

任何包含在

WeakReference(obj)
中的对象都不会被垃圾回收。

您可以通过

target
属性访问该对象,当对象被垃圾回收时,该属性将变为
null

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

3
投票

截至 2020 年,我想在 Günter 的答案中补充一点,我刚刚发布了一个包,通过实现 weak-mapweak-container 来尽可能接近弱引用,如以及利用弱引用的缓存函数

它比 Expando 更容易使用(它内部使用 Expando)。


0
投票

我的项目中需要一个可迭代的 WeakHashMap,因此我使用 WeakReference 和 Finalizer 类实现了一个。这是包裹:

https://pub.dev/packages/weak

除了键是WeakReferenced外,它与其他Dart HashMap具有相同的属性和方法。

© www.soinside.com 2019 - 2024. All rights reserved.