RxSwiftってなんなの？

#はじめに
そろそろ勉強しなきゃという思いとRxSwiftを触ってみたいなという思いがぶつかってQiita書こうと思いました。

#そもそもRxって？
`Reactive Extensions`の略称で`リアクティブプログラミング`を実現するための
設計パターン及び、ライブラリを指します。

元々は、マイクロソフトが自社製品に組み込んでいる.NETフレームワークに向けて開発した.NET用のライブラリ(`Rx.NET`)でしたが、あまりにも強力な技法だったので色んな言語に波及していきました。

それがSwiftにも波及してきて`RxSwift`が開発されました。

#リアクティブプログラミングとは
難しく感じますが、`エクセル`や`スプレッドシート`をイメージすると分かりやすいです。

例えば、このように

A1=1

B1=2

の値を入力してC1に`=A1+B1`という関係を入力します。

![スクリーンショット 2021-05-11 15.15.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/a77dc1a6-5210-fd0b-bff0-30e1787f7605.png)

すると瞬時に計算が走って値が出力されました。

`B1`の値を変えたとしても、`A1`の値を変えたとしても`C1`に計算の答えが瞬時に出力されます。

![スクリーンショット 2021-05-11 15.15.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/e3fb2910-2ea0-3c4d-3996-bf0d107cb94a.png)

このような動きが正に`リアクティブプログラミング`と言われています。

リアクティブプログラミングは`時間軸を重視した`プログラミング方法となっており
`プログラム内での値の変化を時間軸で捉え、値が変わったというイベントによって処理を行います`。

先ほどのエクセルやスプレッドシートの例を図にするとこんな感じ↓

![マーブルダイアグラムの例.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/a3a821b7-568b-0f88-99bb-3a65583f0660.jpeg)

左から右に時間が流れ、そこにイベントが流れてきます。
ここでは`AもしくはBの値が変化したというイベント`が流れます。


そして、イベントが発生したら`A+B=C`という処理が走っています。

上記の図は、正式名称があり`マーブルダイアグラム`と呼ばれています。

下記のサイトに色んなオペレーター(演算)によるマーブルダイアグラムの図が
載っていますので見てみて下さい↓
[RxMarbles](https://rxmarbles.com/)

このようにマーブルダイアグラムでは`時間順に並んだ進行中のイベント`が流れており
これらを`ストリーム`と呼びます。

#Observer(オブザーバー)パターン
`Observerパターン`はRxの根幹となる考え方です。

この考え方には`観測対象`と`観測者`の２つの役割が存在しています。

`観測対象を観測者が観測していて、観測対象の何らかのイベントを観測者が確認したら特定のアクションを起こす`というのが基本の考え方となっています。

ただ実際に実装する際は`観測対象に観測者を登録して、観測対象でイベントが発生したら観測者に知らせて特定のアクションを起こす`といった流れになります。

![オブザーバーパターン.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/cbe460f4-b5ba-27b4-7869-321c3a90ffef.jpeg)

ここでいうイベントは、`ボタンがタップされた`・`文字が入力された`・`APIから値が取得できた`等、プログラム内における`オブジェクトの状態変化すべて`を指します。

#ObservableとObserver
Observerパターンでは次の2つのクラスで`ストリーム`を扱います。

```
・Observable: ストリームを表現するクラス
・Observer： Observableからストリームを受け取るクラス
```

図にすると、こんな感じです↓
![ObservableとObserver.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/021866b0-f465-81a2-a54d-66f8805afadb.jpeg)

#subscribe
Observableは`subscribeメソッド`を持っています。

これは何なのかというと、`通知先を登録するメソッド`です。
つまり、`Observableに対してObserverを登録するメソッド`ですね。

※Observableを`監視`することをsubscribeとも呼んでいます。

先ほどの図で表すとこんな感じ↓

![ObservableとObserver、Subscribe.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/5feeaabf-55d6-4049-8d75-57a6cc541728.jpeg)

#Observableが通知するイベント
Observableが通知するイベントは３種類あり、enumで定義されています。
これらのイベントをObserverが受け取ります。

```swift
public enum Event<Element> {
    // 通常のイベントを通知、値を渡すことができる
    // 複数回送れる
    case next(Element)
    // エラーの発生を通知
    // 発生後はイベントが一切発生しない
    case error(Error)
    // 完了を通知、値を渡せない
    // 発生後はイベントが一切発生しない
    case completed
}
```

図に表すとこんな感じ↓

![Observableが通知するイベント.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/1de80ea8-8aa3-4fb0-64d9-2f4890b1b852.jpeg)

実際にコードで書くとこのようになります↓

```swift
let observable = textField.rx.text.orEmpty.asObservable()
     
observable.subscribe(onNext: { text in
     print(text)

}, onError: { error in
     print(error)

}, onCompleted: { _ in
     print("完了")
})
```
コードを見てみると`流れてきたイベントに対する処理をObservableに登録`しているという見方もできます。

そして、注意して欲しいのが一度、`onCompleted`や`onError`が発生すると
それ以降は`onNext`を呼ぶことが出来ません。

#Disposable
Observableをsubscribeすると、`Disposable`というものを返します。

これは、subscribeしたObservableを`unsubscribe`するための仕組みで
無視するとsubscribeした処理が永遠に解放されずに`メモリリークに繋がる恐れ`があります。

その解決策として`DisposeBag`というものがあります。

これは内部でDisposableを貯めておいて
自身が解放された時に保持しているDisposableを`廃棄`してくれます。

Observableは`disposeメソッド`を持っており、呼び出してDisposeBagを代入する事によって
subscribe時に返される`DisposableをDisposeBagに貯める処理`を定義しています。

```swift
public func disposed(by bag: DisposeBag) {
    // selfがDisposableのこと
    bag.insert(self)
}
```

実際に先ほどのコードで使用した場合↓

```swift
// DisposeBagを初期化する
let dispoceBag = DisposeBag()
let observable = textField.rx.text.orEmpty.asObservable()
        
observable.subscribe(onNext: { text in
     print(text)

}, onError: { error in
     print(error)

}, onCompleted: { _ in
     print("完了")

// 最後にメソッドを呼ぶ
}).disposed(by: dispoceBag)
```

#循環参照に注意する
subscribe時の処理の中のクロージャはselfを`強参照`すると
解放されなくなってしまいます。

なのでselfを`弱参照`しましょう。

```swift
let dispoceBag = DisposeBag()
let observable = textField.rx.text.orEmpty.asObservable()

// weakキーワードでselfを弱参照にする
observable.subscribe(onNext: {[weak self] text in
     print(text)

}, onError: { error in
     print(error)

}, onCompleted: { _ in
     print("完了")

}).disposed(by: dispoceBag)
```

#おわりに
キリがいいのでここで終わります。次回もいつか書こうと思います。

間違っている部分や説明が足りない部分はコメントして教えて下さると有り難いです。

#参考記事
[【Swift】RxSwift勉強してみたPart4](https://qiita.com/REON/items/c986ff93e67e3693324c)
[【RxSwift】Singleton で DisposeBag を使うことの考察](https://blog.cybozu.io/entry/2018/08/15/080000)
[RxSwiftについてようやく理解できてきたのでまとめることにした(1)](https://qiita.com/_ha1f/items/e16ddc6017c4ad807c3c)
[SwiftでReactive Programming - Qiita](https://qiita.com/shoheiyokoyama/items/60aa617ab39778d73110#reactive-programming)
[Rx入門 (2) - オブザーバーパターン - xin9le.net](https://blog.xin9le.net/entry/2011/12/10/153032)
[RxSwiftでiOSアプリ開発～リアクティブプログラミングを導入する - CodeZine](https://codezine.jp/article/detail/11000)