【RxSwift】materialize, dematealizeを使ってみた

公開日: : iOSアプリ開発

@toshi0383さんに教えていただいた、RxSwiftのmaterializeを使ってみました。

materializeとは何か?

materializeを使うと、Observable<T>をObservable<Event<T>>に変換することができます。

コードと実行結果を見たほうが理解しやすいかもしれません。

materializeを使ってみる

ではさっそくmaterializeを使ってみましょう。nextとcompletedを流してみます。

let subject = PublishSubject<Int>()

subject
	.materialize()
	.subscribe(onNext: { (event: Event<Int>) in
		print("onNext", event)
	}, onError: { error in
		print("onError", error)
	}, onCompleted: {
		print("onCompleted")
	}, onDisposed: {
		print("onDisposed")
	}).disposed(by: disposeBag)

	subject.onNext(100)
	subject.onCompleted()

以下、実行結果です。流したnextとcompletedがnextにラップされていることが分かります。また、ラップされていないcompletedも流れています。これについては後述します。

onNext next(100)

onNext completed

onCompleted

onDisposed

次はnextとerrorを流してみます。

let subject = PublishSubject<Int>()

subject
	.materialize()
	.subscribe(onNext: { (event: Event<Int>) in
		print("onNext", event)
	}, onError: { error in
		print("onError", error)
	}, onCompleted: {
		print("onCompleted")
	}, onDisposed: {
		print("onDisposed")
	}).disposed(by: disposeBag)

subject.onNext(100)
subject.onError(Error())

以下、実行結果です。流したnextとerrorがnextにラップされていることが分かります。また、先ほどと同様にラップされていないcompletedも流れています。

onNext next(100)

onNext error(Error())

onCompleted

onDisposed

dematealizeを使ってみる

materializeの反対の操作、つまりObservable<Event<T>>をObservable<T>に変換してくれるdematealizeというメソッドも用意されています。

let subject = PublishSubject<Int>()

subject
	.materialize()
	.dematerialize()
	.subscribe(onNext: { (num: Int) in
		print("onNext", num)
	}, onError: { error in
		print("onError", error)
	}, onCompleted: {
		print("onCompleted")
	}, onDisposed: {
		print("onDisposed")
}).disposed(by: disposeBag)

subject.onNext(100)
subject.onError(Error())

以下、実行結果です。materializeの後にdematerializeを呼ぶことで、元々のストリームに戻っていることが分かります。

onNext 100

onError Error()

onDisposed

Eventでラップされていないcompletedも流れる

materializeはcompletedをnextでラップするだけでなく、nextでラップされていない普通のcompletedも流します。

以下の記事で示されている図を見ると理解しやすいと思います。

ReactiveX – Materialize & Dematerialize operators

また、以下のページでmaterializeのコードを読むと、errorまたはcompletedが流れてきた時は、nextでラップして流した後にnextでラップされていないcompletedを流していることが分かります。

RxSwift/Materialize.swift at master · ReactiveX/RxSwift

なお、materializeの実装で使っているisStopEventのコードは以下のページで確認できます。errorまたはcompletedの時にtrueを返しています。

RxSwift/Event.swift at master · ReactiveX/RxSwift

まずは普通にmaterializeを使ってみましょう。

let subject = PublishSubject<Int>()

subject
	.materialize()
	.subscribe(onNext: { (event: Event<Int>) in
		print("onNext", event)
	}, onError: { error in
		print("onError", error)
	}, onCompleted: {
		print("onCompleted")
	}, onDisposed: {
		print("onDisposed")
	}).disposed(by: disposeBag)

subject.onNext(100)
subject.onCompleted()

以下、実行結果です。nextでラップされたnext(100)と、nextでラップされたcompletedが流れていることが分かります。

onNext next(100)

onNext completed

onCompleted

onDisposed

次に、filterですべてのnextを除去してみましょう。

let subject = PublishSubject<Int>()

subject
	.materialize()
	.filter{ _ in false }
	.subscribe(onNext: { (event: Event<Int>) in
		print("onNext", event)
	}, onError: { error in
		print("onError", error)
	}, onCompleted: {
		print("onCompleted")
	}, onDisposed: {
		print("onDisposed")
	}).disposed(by: disposeBag)

subject.onNext(100)
subject.onCompleted()

以下、実行結果です。先ほどのnextでラップされたnext(100)と、nextでラップされたcompletedは除去されましたが、nextでラップされていないcompletedは先ほどと変わらず流れています。

onCompleted

onDisposed

この記事を書いた人
あきお(@akio0911
iOSエンジニア、ブロガー。「プログラミングで人々を幸せに」をテーマに活動中。著書に「iPhoneアプリ開発レシピ」「cocos2d for iPhoneレッスンノート」など。東京・大阪にてアプリ開発講座「アプリクリエイター道場」を主催。 MAMORIO株式会社 技術顧問(インタビュー記事)、VISITS Technologies株式会社 技術顧問(インタビュー記事)。ブログ「卵は世界である」を運営。

関連記事

この記事が気に入ったら「いいね!」しよう

follow us in feedly

Feedlyで最新記事を購読

Twitterで更新情報をゲット!

LINEでご感想・ご要望お送りください!
(スマホでLINEを起動 > 友だち追加 > QRコード)

【入門】プログラム・プログラミング・プログラミング言語とは?

こんにちは、@akio0911です。 今回は「プログラム」「プロ

【入門】プログラミング未経験者向けのプログラミング入門連載記事を始めます

こんにちは、@akio0911です。 これからプログラミング未経

【RxSwift】BehaviorRelayとPublishRelayについてまとめてみた

こんにちは、@akio0911です。今回はRxSwiftのBe

【RxSwift】materialize, dematealizeを使ってみた

@toshi0383さんに教えていただいた、RxSwiftのm

【RxSwift】ストリームのcompletedをつぶす(消し去る)方法

RxSwiftで元々のストリームからcompletedをつぶす

→もっと見る

PAGE TOP ↑