【RxSwift】Subjectとは?Relayとの違いと使い方

この記事からわかること

  • RxSwiftSubjectRelay違い使い方
  • PublishBehaviorの違い

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

RxSwiftのイベントの検知と発生を行えるクラスであるSubjectとRelayの概要と使い方などをまとめていきます。

おすすめ記事:【RxSwiftとは?導入方法と使い方まとめ!ストリームを理解する

Subjectとは?

SubjectとはRxSwiftにおけるイベントの検知と発生が可能なクラスです。RxSwiftにおいてイベントの検知が可能なクラスといえばObservableクラスですがさらに自身でイベント流せるのが大きな違いです。

流せるイベントはonNextonErroronCompletedの3つです。

さらにSubjectの中には「Publish」と「Behavior」に分かれそれぞれのクラスが定義されてます。両者の違いはバッファ(※)を持つか持たないかです。バッファを持つBehaviorは過去のイベントを受け取ることができるようになります。

※バッファとはデータを一時的に記憶する場所を指すような言葉です。

Relayとは?

RelayもSubjectと同じイベントの検知と発生が可能なクラスです。

ただしこちらは流せるイベントがonNextのみとなっています。「Publish」と「Behavior」に分かれる点は同じです。

まとめ

クラス名 流せるイベント バッファ
PublishSubject onNext、onError、onCompleted
BehaviorSubject onNext、onError、onCompleted
PublishRelay onNext
BehaviorRelay onNext

Subjectの使い方

Subjectは自身でイベントを流せるクラスでした。これを使って独自でイベントを発生させるViewModelクラスを作成してみます。ここでのポイントは以下の通りです。

import UIKit
import RxSwift
import RxCocoa

class SampleModel{
    private var subject = PublishSubject<String>()
    
    public var observable :Observable<String>{
        return subject.asObservable()
    }
    
    func call(){
        subject.onNext("Hello World")
        subject.onCompleted()
    }
}

ViewModelとして使用したいのでイベントの発行が内部のみに限定するためにprivateで定義し、Observableクラスには外部から使用できるように分かりやすくpublicを付与しておきます。

あとは任意のイベントを任意の回数定義したメソッドなどを用意しておけばViewModelを介してイベントの発行と取得を行うことができるようになります。

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    
    private let disposeBag = DisposeBag()
    private let viewModel = SampleModel()
    private var label = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        label.frame = CGRect(x:0, y:0,width:100, height:50)
        label.text = "placeholder..."
        label.center = self.view.center
        self.view.addSubview(label)
        
        // 購読開始
        viewModel.observable.subscribe { text in
            self.label.text = text
        }.disposed(by: disposeBag)
        
        // イベントを発火
        viewModel.call()
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index