RxSwiftについてようやく理解できてきたのでまとめることにした(1)


# RxSwiftとは

最近流行ってる（？）FRPのフレームワークの一つです。

非同期処理のコールバック地獄をとてもシンプルに書くことができます。
また、RxKotlinなどとも似ているので、Androidとも似たようにかけるのもメリットの一つだと思います。

[github.com/ReactiveX/RxSwift](https://github.com/ReactiveX/RxSwift)もそこそこのSTAR数になっているし、実プロジェクトでもそこそこ採用されているので、さほど恐れることもないのではなかろうか

# これからのプラン
1. Observableの基本
2. Observableの生成について
3. Observableの基本的な変換〜filter, map, flatMap〜
4. HOT/COLDについてと、それにまつわるオペレータ
5以降：その他変換、Observableの仲間、… について

どんだけ時間取れるかわからないですが、こんな感じでかければ良いかなーと。

ターゲットは、RxSwiftの記事を読んでも画像の意味がわからない！人向けです
とはいえ画像作るの下手なので、テキストですが、具体例多めに入れながらかけたら良いなと思ってます

### 個人的に考えるメリット・デメリット

メリット

- コード全体が一貫する
- まとまった流れが見やすい、差分がわかりやすい
- スレッドを変えやすい
- コールバック地獄になりにくい


デメリット

- 学習コストが高い
- 長くなりがちで、パット見はわかりにくい

# Observable入門

RxSwiftの基幹をなす概念と言ってもいいObservable。「監視できる」という名前ですが、とりあえず「イベントを流すもの」です

Observableの簡単な例を見てみましょう。これはtextFieldに入力された値に関するObservableの例です。

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

これを実行すると、textFieldに入力された値が変わるたびに、その値が `print` されます。
つまり、「値が更新されるたびに、登録された処理を実行」します。

ここの `textField.rx.text.asObservable()` が observableです。
observableが「値が更新されたというイベント」を流して、
そのイベントに対して「登録された処理」を行う（今回だと `{ string in print(string) }` ）

# onNext, onCompleted, onError

Observableは、以下の3種類のイベントを流します

- onNext
- onCompleted
- onError

それぞれ、onNextは「値が更新された」, onCompletedは「処理が完了した」, onErrorは「エラーが発生した」というイベントを表します。

onNextは値を渡すことができますが、onCompletedは値を渡すことができません。以下のような定義ですね。([RxSwift/Event.swift](https://github.com/ReactiveX/RxSwift/blob/master/RxSwift/Event.swift#L13L22))

```swift
public enum Event<Element> {
    case next(Element)
    case error(Swift.Error)
    case completed
}
```

３つだけですが、これら３つの組み合わせでいろいろな動作を表すことができます。

例えば、URLから何かをダウンロードするような処理は結果は一つだけなので、

```
通信開始 -> onNext(通信結果) -> onCompleted
```

インターネット接続がなかった場合は

```
通信開始 -> onError("no internet")
```

他にも例えば画像を取得する場合などで、先にサムネイルを取得した後にオリジナル画像を取得するシーンなどは、

```
取得開始 -> onNext(サムネイル) -> onNext(オリジナル画像) -> onCompleted
```

アニメーションの処理完了などのように値を渡す必要が無い場合は

```
アニメーション開始 -> onCompleted
```

のようになります。

これが、Observableです。RxSwiftの世界では、いろいろな動作をObservableとみなして、上の3つのイベントの形で扱います。

※ ルールとして、一度onCompletedやonErrorが発生するとそれ以降onNext等を呼ぶことはできなくなるので注意（複数のonCompletedが必要な場合は、それぞれをObservableにするか、onNextとして流す）

# subscribe（購読）

もう一度先程のサンプルを見てみましょう

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

ここのonNextは、ObservableからonNextイベントが流れてきた時の処理として、 `{ string in print(string) }` を登録している事になります。同様に、onCompleted, onErrorなどにも登録することができます。

```swift
let observable = textField.rx.text.asObservable()
let subscription = observable
    .subscribe(onNext: { string in
        print(string)
    }, onError: { error in
        print(error)
    }, onCompleted: { _ in
        print("completed")
    })
```

この登録された処理のことを observerと呼びます。名前はObservableと似ていますが、意味は逆なので注意してください！

※subscribeにはもう一つ大きな意味がありますが、HOT/COLDの章で書きます。

# dispose（購読解除）

subscribe処理をいつまでも続ける訳にはいきません。これを止めることをdisposeと呼びます。クロージャなどがメモリ解放されます。

先程のコードに、

```swift
subscription.dispose()
```

のようにするとdisposeできます。

onCompletedやonErrorが発生するとObservableはもうイベントを発行できないので、自動的にdisposeされます。よって、明示的にdisposeする必要はありません。

disposeは適切に行わないと、メモリリークします。が、一つ一つ開放処理を書くとバグが発生しやすいです。そこで、DisposeBagを使うと半自動的に解放をしてくれるのでよく使います。

### DisposeBag

disposeBagは、disposeBagオブジェクト自身が開放されるタイミングで、登録されたsubscriptionをdisposeします。

```swift
{
    let disposeBag = DisposeBag()
    Observable<Int>.never()
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
}()
```

`Observable<Int>.never()` はonCompletedを流さないobservableです。これをsubscribe()しただけだといつまでたってもdisposeされませんが、disposeBagに登録しておくとこのクロージャを抜けた時にdisposeBagは開放されるので、そのタイミングで購読処理も解除されます。

これはViewControllerなどで非常に便利で、RxSwiftを使うプロジェクトではViewControllerのメンバには必ずと言ってよいほど定義して、画面に関わるsubscriptionを登録しておくことが多いです。

# 循環参照の防止

注意しなければならないのは、購読処理の中のclosureでself等を強参照すると解放されなくなってしまうので、 `weak` または `unowned` にしなければいけないことです。
基本的には、closureが実行される段階ではdisposeBagがdisposeされていない、すなわちselfも存在しているはずなので `unowned` で問題ないと思いますが、中で更に非同期処理を実行している場合などは注意が必要です。

例

```swift
observable
    .subscribe(onNext: { [unowned self] string in
        self.textLabel.text = string
    })
    .disposed(by: disposeBag)
```

また一般的に、データを流すとき、できるだけクラスではなく構造体を使うなどして、外部変数へのキャプチャや副作用はなくしたほうが良いです。

# Observable\<Element\>

最後になりましたが、ObservableはGenericに定義されています。一つのObservableが複数回のonNextを呼んだとしても、渡される値の型は必ず同じです。
`Observable<String>` なら必ずonNextイベントではString型の値が渡されます。

もちろん、引数などからElementが推測される場合は型を明示する必要はありません。

複数の値を渡す場合は、

- まとめた構造体をつくる
- タプルにまとめる

等を行います。

# まとめ

ObservableはonNext(element), onCompleted, onError(error)の3種類のイベントを流します。

イベントの受け取り(observer)側は、流れてきたイベントに対する挙動を登録するんだ、ということだけ意識すれば良いです。

続き→https://qiita.com/_ha1f/items/43b28792d27dbee7133d