🙆

asStateFlowとasSharedFlowが何をやっているのか?

2022/06/25に公開

ViewModelで、stateFlowやSharedFlowを使用するときに、下記のような感じで書くときに出てくるasStateFlowasSharedFlowがなんとなく使っていたので、どういった処理が内部で行われているのか見てみました。

val _uiState = MutableStateFlow<UiState>(UiState.Proceeding)
val uiState: StateFlow<UiState>() = _uiState.asStateFlow()

asStateFlow、asSharedFlowって何をやっているのか?

実際に、asStateFlowasSharedFlowの中身を見てみると、、、

private class ReadonlySharedFlow<T>(
    flow: SharedFlow<T>,
    @Suppress("unused")
    private val job: Job? // keeps a strong reference to the job (if present)
) : SharedFlow<T> by flow, CancellableFlow<T>, FusibleFlow<T> {
    override fun fuse(context: CoroutineContext, capacity: Int, onBufferOverflow: BufferOverflow) =
        fuseSharedFlow(context, capacity, onBufferOverflow)
}

private class ReadonlyStateFlow<T>(
    flow: StateFlow<T>,
    @Suppress("unused")
    private val job: Job? // keeps a strong reference to the job (if present)
) : StateFlow<T> by flow, CancellableFlow<T>, FusibleFlow<T> {
    override fun fuse(context: CoroutineContext, capacity: Int, onBufferOverflow: BufferOverflow) =
        fuseStateFlow(context, capacity, onBufferOverflow)
}

こんな感じになってました。

Mutableな値が内部で、Readonlyになっているようです。

valになってるなら変更できないんじゃないか?と思ったんですが、valはフィールドに別の値を設定できないことを意味するらしく、フィールドに対して操作を実行することはできるらしいです。

Readonlyになると、操作を実行することを制御するということもできるようになり、安全性が増すということがわかりました。

参考

https://stackoverflow.com/questions/71276772/why-do-the-author-need-to-use-asstateflow-in-compose

Discussion