问题描述
我有一个 cubit 来监听消息流,并发出一个保存消息的状态。 在屏幕中,我使用 BlocProvider 来访问肘,并使用 BlocBuilder 来显示 消息。
在下面的例子中,我是否需要关闭在 listen() 上创建的 StreamSubscription?有没有干净的方法来做到这一点?
class MessageCubit extends Cubit<MessageState> {
final GetMessagesUseCase getMessagesUseCase;
MessageCubit({this.getMessagesUseCase}) : super(MessageInitial());
Future<void> getMessages({String senderId,String recipientId}) async {
emit(MessageLoading());
try {
final messagesstreamData = getMessagesUseCase.call();
//This is where I listen to a stream
messagesstreamData.listen((messages) {
emit(MessageLoaded(messages: messages));
});
} on SocketException catch (_) {
emit(MessageFailure());
} catch (_) {
emit(MessageFailure());
}
}
}
解决方法
您不需要需要关闭订阅,但您应该作为避免潜在内存泄漏的好习惯。既然如此简单,就没有任何牺牲。
- 创建一个
StreamSubscription<your type>
类型的类变量。假设它名为sub
。 - 在听之前在 getMessages 中:
await sub?.cancel()
- 然后
sub = messagesStreamData.listen(...
- 覆盖 Cubit 的
close
方法并运行与第 2 项中相同的命令。
完整代码:
class MessageCubit extends Cubit<MessageState> {
final GetMessagesUseCase getMessagesUseCase;
// Added
StreamSubscription<YOUR_MESSAGES_TYPE> sub;
MessageCubit({this.getMessagesUseCase}) : super(MessageInitial());
Future<void> getMessages({String senderId,String recipientId}) async {
emit(MessageLoading());
try {
final messagesStreamData = getMessagesUseCase.call();
// Added
await sub?.cancel();
//This is where I listen to a stream
sub = messagesStreamData.listen((messages) {
emit(MessageLoaded(messages: messages));
});
} on SocketException catch (_) {
emit(MessageFailure());
} catch (_) {
emit(MessageFailure());
}
}
// Added
@override
Future<void> close() async {
await sub?.cancel();
return super.close();
}
}