【RxSwift】Hot変換オペレータの1つであるshareReplayを使ってみる

公開日: : iPhoneアプリ開発

20160423-124300.jpg

最近、RxSwiftについて勉強中です。

今回は、Hot変換オペレータの1つであるshareReplayを使ってみたので記事にまとめてみました。

RxSwiftはまだ勉強中なので、どこか間違っている箇所があればご指摘いただけると嬉しいです。 ⇒ https://twitter.com/akio0911

    

スポンサード リンク

UITextFieldの入力をそのまま2つのUILabelに表示する

例として、1つのUITextFieldに入力された文字列を、2つのラベルにそのまま表示するアプリを考えてみましょう。

RxSwiftを使ったコードとしては、以下のようになります。

@IBOutlet weak var textField: UITextField!

@IBOutlet weak var label1: UILabel!
@IBOutlet weak var label2: UILabel!

let disposeBag = DisposeBag()

override func viewDidLoad() {
    super.viewDidLoad()

    textField.rx_text.bindTo(label1.rx_text).addDisposableTo(disposeBag)
    textField.rx_text.bindTo(label2.rx_text).addDisposableTo(disposeBag)
}

これでユーザーがテキストフィールドに文字列を入力すると、ラベルへリアルタイムに反映されるようになります。

ここまでは特に問題ないかなと思います。

    

UITextFieldの入力を加工して、2つのUILabelに表示する

次はそのまま表示せずに簡単な加工を行ってみましょう。

テキストフィールドに入力された文字列の先頭と末尾に*を付加し、それを2つのラベルへリアルタイムに反映させます。

コードは以下のようになります。

let num = textField.rx_text.map{ text -> String in
    print("map \(text)")
    return "*\(text)*"
}

num.bindTo(label1.rx_text).addDisposableTo(disposeBag)
num.bindTo(label2.rx_text).addDisposableTo(disposeBag)

    

さて、このコードを早速実行してみましょう。

map 
map 
map 1
map 1
map 12
map 12

なんと、文字に変更を加えるたび、mapのクロージャー内の処理が2回ずつ実行されてしまっています。

今回の場合だと同じ加工を施した同じ内容を2つのラベルに表示させたいので、mapのクロージャー内の処理は1変更に対して1回だけ実行されればいいのですが・・・。

    

20160423-123905.jpg

なぜこのようなことが起こってしまったのかというと、2つのオブジェクトにbindしsubscribeすると、別々の2本のストリームが生成されてしまうんだそうです。

このような性質を持つものを、Cold Observableと呼ぶようです。

参考 : RxのHotとColdについて – Qiita

今回のような軽い処理であれば大きな問題にはなりませんけど、重い処理だったり、ファイルIOや通信処理などが含まれていたりすると、それらが2回ずつ実行されると困りますよね。

    

shareReplayを使ってみる

ではどうすれば良いのかというと、Coldと呼ぶくらいですから、Hot Observableを使います。

Cold ObservableをHot Observableに変換してくれる「Hot変換オペレータ」というものがあるので、その中の1つである「shareReplay」を使います。

let num = textField.rx_text
    .map{ text -> String in
        print("map \(text)")
        return "*\(text)*"
    }
    .shareReplay(1)

num.bindTo(label1.rx_text).addDisposableTo(disposeBag)
num.bindTo(label2.rx_text).addDisposableTo(disposeBag)

shareReplay(1)は、内部的にはreplay(1).refCountを呼び出してるだけのショートカットなんだそうですが、詳細についてはまた別記事を書こうと思います。

参考 : [RxSwift] shareReplayをちゃんと書いてお行儀良くストリームを購読しよう – Qiita

    

実行結果は以下のようになります。

map 
map 1
map 12
map 123

テキストフィールドへの1変更に対して、mapのクロージャー内の処理が1回ずつ呼ばれています。

    

20160423-123910.jpg

これは、Hot Observerの「ストリームを分岐する性質」によるものだそうです。

    

@akio0911はこう思った。

Cold ObservableとHot Observableの違いが分かっていないと、意図せず無駄な処理が発生してしまいそうなので、ここは注意が必要ですね。

    

    

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

follow us in feedly

Feedlyで最新記事を購読

Twitterで更新情報をゲット!

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

関連記事

I20160102-131507.jpg

Swift 2の文法が分かるオススメ本「詳解 Swift 改訂版」

Swift文法書の定番とも言える、荻原 剛志さんの「詳解 Swift」。 Swiftの文法をキ

記事を読む

I20150802-085831.jpg

Swift 1.2でtouchesBeganメソッドのNSSetがSetへ変更されました

Swift 1.2で、touchesBegan・touchesMoved・touchesCanc

記事を読む

I20160418-235604.jpg

XcodeのStoryboardで部品を選択しやすくする2つの方法

ストーリーボード上で部品が入り組んでくると選択しづらくなってきますが、そんな状況でも部品を選択し

記事を読む

I20160128-101452.jpg

【解決】Playground execution terminated because the process stopped unexpectedlyが出た時の対処法

Xcodeのプレイグラウンドで「Playground execution terminated

記事を読む

I20150907-185322.jpg

uGUIの使い方が分かる本「uGUIではじめるUnity UIデザインの教科書」

株式会社マイナビ様より献本御礼。 本書は、公式のUIフレームワーク「Unity UI(uGUI

記事を読む

I20160918-133158.jpg

StoryboardでChild View Controllerにデータを渡す方法(Xcode 8 & Swift 3)

Storyboardで、Child View Controllerにデータを渡す方法を紹介します

記事を読む

20160807-113229.jpg

UITableViewのリサイズに合わせて一番下のセルを常に一番下に表示する方法

一番下のセルを表示している状態でUITableViewの下端を上に移動させると一番下のセルが隠れ

記事を読む

20150525-224340.jpg

【Swift】クロージャをメソッドや関数の引数として渡す方法

Swiftでメソッドの引数としてクロージャを渡す方法について解説したいと思います。     

記事を読む

I20151030-214417.jpg

【開発本】SpriteKitの入門書籍「iPhoneのゲームアプリをつくろう!」

SwiftとSpriteKitでiPhoneゲームアプリを開発するための入門書「iPhone

記事を読む

20150409-103620.jpg

描いたベクターグラフィックをSwift/Objective-Cコードに変換できる「Paint Code 2」

引用元 : PaintCode ベクターグラフィックを描き、それを描画するためのSwift

記事を読む

20170423-182541
良肌研究室のフェイスウォッシュとオールインワンジェルを使ってみた

株式会社ブラシナさんから、良肌研究室の商品をご提供頂いたので、

I20170228-002742.jpg
約3ヶ月で体脂肪率を6.2%も落とせたキッカケについて

(右上の赤枠内がダイエット開始前、左下の赤枠内が3ヶ月後の数値

I20161224-174949.jpg
「季節の野菜を直接配送!季節のスムージー」を買ってみた

「FiNCモール」で、「季節の野菜を直接配送!季節のスムージー」を

I20161002-152537.jpg
【メンズネイル】東京・新宿のネイルサロンでマットネイルしてもらった

2016年7月18日、東京・新宿のメンズOKなネイルサロン「Tot

I20160925-163452.jpg
タブバーアイコン非選択時の色を変更する方法【iOS 10】

UITabBarControllerで、タブバーアイコン非選択時の

→もっと見る

PAGE TOP ↑