Reputation: 4064
In Flutter, if I obtained a StreamSubscription
from a Stream
, what is the proper etiquette to clean up resources when I am done?
Stream
doesn't have a cancel
method so I can't clean up that.StreamSubscription
has a cancel
method but does calling cancel
here also cancel the corresponding Stream
too?Stream
closes by itself when it is done, will it automatically signal to SteamSubscription
to cancel automatically, meaning I don't need to manually close it? Otherwise it will hold a list of listeners somewhere and prevent garbage collection.I can imagine 2 hypothetical scenarios:
A Stream
implementation that just returns a never ending list of increasing even numbers. Ideally, Stream
should never cancel itself and shouldn't generate output unless there is an active subscription too. This meaning canceling a subscription should be enough to free all resources and prevent Stream
from running further.
A Stream
implementation that listens for clicks on a button. Ideally, the Stream
should offer a cancel method when the user is no longer interested in listening to clicks. If the user calls cancel
on the StreamSubscription
only, will this also cancel the Stream
? If somewhere upstream there is code that canceled the Stream
such as the button being garbage collected, is the StreamSubscription
automatically canceled and all references cleared?
Upvotes: 1
Views: 1070
Reputation: 960
Stream
has two types, "Single-subscription" streams and "broadcast" streams [1]. single subscription uses async*
which generates the stream within a method body, this is a cold stream that only works when it is subscribed to and it ends the stream when the method body is exited or when the single subscriber cancels. On the other hand, broadcast streams are hot streams that have a StreamController
that can be used to emit to the Stream
or cancel it but you would need to have access to the parts that generate that Stream
.
Canceling the subscription will cancel cold streams since they have only one subscriber. Made an example for it here. And for broadcast/hot streams, you have full control with a StreamController
, so you can cancel the stream or not, but it's recommended to do so when the last subscriber un-subscribes [2].
When a Stream
closes, it un-subscribes all listeners and then inform them of the event [1], you can pass a function to onDone
when listening to a Stream
to receive this event.
As for the titled question, the stream has a reference to your object when you subscribe to it and should be freed explicitly even though the Stream
may eventually clean it up on its own.
Upvotes: 5