🌊

PassThroughSubjectとCurrentValueSubjectの特徴と違い

2024/05/14に公開

はじめに

本記事では、WWDC2019で発表されたCombineフレームワークの中の2つのSubjectの違いについて、取り上げたいと思います!
Combineで用意されているSubjectは、

  • PassThroughSubject
  • CurrentValueSubject

の2つです。
このふたつのsubjectはCombineの説明の記事などで度々登場するのですが、

Combineの概要をまず簡単に掴みたい方は、WWDC2019のCombineの動画はこちら。

https://developer.apple.com/videos/play/wwdc2019/721/

https://developer.apple.com/videos/play/wwdc2019/722/

まず結論

2つのSubjectの特徴は、
PassThroughSubjectは、

  • 初期値を持たない。
  • 受け取った値をブロードキャストする。
  • .sendメソッドを持つ。

CurrentValueSubject

  • 初期値を持ち、最後に発行された値を保持する。
  • .sendメソッドを持つ。

PassThroughSubjectとCurrentValueSubjectの違いをイメージとコードで理解する

アプリ道場サロンでの勉強会でakioさんに教えて頂いたときのイメージを拝借しています。

  • PassthroughSubject
    こちらは、一つずつ以下のように送られてくるイメージです。
    ---(1)---(2)---(3)--->

  • CurrentValueSubject
    反対に、こちらは値が途切れず、連なって送られてくるイメージです。
    ---111122223333---->

PassThroughSubjectの挙動を確認する

let subject = PassthroughSubject<Int, Never>()

subject
	.sink { value in
	    print("##### \(value)")
	}
    
// PassthroughSubjectに新しい値を発行する
subject.send(1) // Received value: 1
subject.send(2) // Received value: 2
subject.send(3) // Received value: 3

CurrentValueSubjectの挙動を確認する

let subject = CurrentValueSubject<Int, Never>(0)

subject
    .print() // PublisherとSubscriberとのやり取りをコンソールに出力するデバック用のメソッド
    .sink { value in
        print("#### \(value)")
    }

subject.send(1)
subject.send(2)
subject.send(3)

コンソール上の出力結果:

receive subscription: (CurrentValueSubject)
request unlimited
receive value: (0)  // 最初に、初期値0が自動で受信処理されている。
#### 0
receive value: (1) // .send(1)を受信
#### 1
receive value: (2) // .send(2)を受信
#### 2
receive value: (3) // .send(3)を受信
#### 3
receive cancel // 受信処理が完了し、Subscriberがキャンセルされる。

おわりに

2つのSubjectの特徴は、PassThroughSubjectCurrentValueSubjectの挙動の違いについて、理解することができました。

今後は、これを実際のアプリでどのように活用していくのか模索していきたいと思います!

参考

https://developer.apple.com/videos/play/wwdc2019/721/

https://developer.apple.com/videos/play/wwdc2019/722/

https://developer.apple.com/documentation/combine/subject

https://developer.apple.com/documentation/combine/passthroughsubject

https://developer.apple.com/documentation/combine/currentvaluesubject

Discussion