Flutter: 在 @riverpod 生成的提供程序中释放资源

huangapple go评论60阅读模式
英文:

Flutter: Disposing of resources in @riverpod generated provider

问题

我在我的Flutter应用中使用riverpod_generator生成一个供应程序(provider),用于控制器(controller)。该控制器实际上是一个Notifier。

我想知道在控制器中设置资源的处理(在本例中为BehaviorSubject及其流的订阅)的正确位置在哪里。

像我在包含的代码中所做的那样,在build()方法中这样做可以吗?
谢谢。

英文:

I am using riverpod_generator in my Flutter app to generate a provider for a controller that I use. The controller is actually a Notifier.

I am wondering where is the correct place in the controller to set up the disposal of resources (in this case, a BehaviorSubject, and its stream's subscription.

Is it ok to do it in the build() method, as I have in the included code?
Thanks

part "provider.g.dart";

final PlayersSearchFiltersValue _initialFilters = PlayersSearchFiltersValue(
  searchTerm: "",
);

@riverpod
class PlayersSearchAppController extends _$PlayersSearchAppController
    implements PlayersSearchController {
  late final PlayersService playersService =
      ref.read(playersAppServiceProvider);

  final BehaviorSubject<PlayersSearchFiltersValue> _filtersSubject =
      BehaviorSubject();
  late StreamSubscription<PlayersSearchFiltersValue> _filtersSubscription;
  StreamSink<PlayersSearchFiltersValue> get _filtersSink =>
      _filtersSubject.sink;

  @override
  AsyncValue<List<PlayerModel>> build() {
    _initializeController();
    return AsyncValue.data([]);
  }

  /// rest of the code

  void _initializeController() {
    _filtersSubscription = _filtersSubject.stream
        .debounceTime(Duration(milliseconds: 500))
        .listen((event) {
      _onSearchPlayers(event);
    });

    ref.onDispose(() async {
      await _filtersSubscription.cancel();
      await _filtersSubject.close();
    });
  }
}

答案1

得分: 2

是的,这将很好地工作。也许唯一的事情是定义一个单独的 _dispose 方法,并将这部分代码分配给它,以共享责任。


  @override
  AsyncValue<List<PlayerModel>> build() {
    _initializeController();
    _dispose();
    return AsyncValue.data([]);
  }

  void _dispose() {
    ref.onDispose(() async {
      await _filtersSubscription.cancel();
      await _filtersSubject.close();
    });
  }

  void _initializeController() {
    _filtersSubscription = _filtersSubject.stream
        .debounceTime(Duration(milliseconds: 500))
        .listen((event) {
      _onSearchPlayers(event);
    });
  }

此外,您应该记住,默认情况下生成器会创建会丢弃其状态的提供程序(例如使用 dispose 修饰符)。要更改此行为,请使用:

@Riverpod(keepAlive: true)
英文:

Yes, this will work great. The only thing, perhaps, is to define a separate _dispose method and allocate this piece of code to it in order to share responsibilities.


  @override
  AsyncValue&lt;List&lt;PlayerModel&gt;&gt; build() {
    _initializeController();
    _dispose();
    return AsyncValue.data([]);
  }

  void _dispose() {
    ref.onDispose(() async {
      await _filtersSubscription.cancel();
      await _filtersSubject.close();
    });
  }

  void _initializeController() {
    _filtersSubscription = _filtersSubject.stream
        .debounceTime(Duration(milliseconds: 500))
        .listen((event) {
      _onSearchPlayers(event);
    });
  }

Also, you should remember that generator by default creates providers that dispose their state (as with the dispose modifier). To change this behavior, use:

@Riverpod(keepAlive: true)

huangapple
  • 本文由 发表于 2023年5月7日 14:37:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76192520.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定