web-dev-qa-db-ja.com

StreamBuilderは、ステートレスウィジェットのストリームを自動的にオフにしますか?

FlutterでBLOCを使用する場合、たとえば:

_class StreamText extends StatelessWidget {
  StreamText(
    this.stream, {
    this.style,
  });

  final Stream<dynamic> stream;
  final TextStyle style;

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<dynamic>(
      stream: stream,
      builder: (context, snapshot) {
        return Text(snapshot.data.toString(), style: style);
      },
    );
  }
}
_

これはステートレスウィジェットであり、dispose()メソッドはありません。

そして、どのように私はストリームをオフにすることができますか、またはこのウィジェットが破壊されたときにそれをストリームから自動的にオフにしますか?

7
junk

いいえ、それはStreamを閉じませんが、ウィジェットの構築に使用されるStreamSubscriptionを閉じます。

Streamを他の目的で使用しない場合は、Streamを何らかの方法で破棄することをお勧めします(StatefulWidgetでラップするか、BlocProviderアプローチを使用します)。

他の場所でStreamを使用している場合、または将来Streamを使用する場合、StreamBuilderで使用するためにメモリがリークすることを心配する必要はありません。限りあなたが他の人がそれを使用しなくなったときはいつでもそれを処分するので。

StreamBuilder自体はStreamBuilderBaseから拡張されます。これはStatefulWidgetであり、独自のStreamSubscriptionメソッドでdisposeを処理します。

これはasync.Dartライブラリからの抜粋です。

/// State for [StreamBuilderBase].
class _StreamBuilderBaseState<T, S> extends State<StreamBuilderBase<T, S>> {
  StreamSubscription<T> _subscription;

  @override
  void initState() {
    //...
    _subscribe();
  }

  @override
  void dispose() {
    _unsubscribe();
    super.dispose();
  }

  void _subscribe() {
    if (widget.stream != null) {
      _subscription = widget.stream.listen((T data) {
    //...
    }
  }

  void _unsubscribe() {
    if (_subscription != null) {
      _subscription.cancel();
      _subscription = null;
    }
  }
}

ご覧のとおり、StreamSubscriptioninitStateで初期化され、Stateのdispose呼び出しで自動的にキャンセルされるため、ここで使用されるサブスクリプションは常に閉じられ、心配する必要はありません。

1
Evin1_

ステートレスウィジェットでは、ウィジェットがウィジェットツリーから削除されると、StreamBuilder自体が「自動オフ」になります。何も処理する必要はありません。

ただし、スナップショットを送信するStreamControllerがある場合は、完了したら手動で閉じる必要があります。

1
Kirill Karmazin