LoginSignup
2
4

More than 1 year has passed since last update.

[RxSwift6.0] withUnretained(_: )オペレータについて

Posted at

はじめに

本記事ではRxSwift6.0から追加されたwithUnretained(_:)オペレータについてどんなものか追求していこうという記事です。
ぜひ最後まで読んでいただければと思います!

前提

RxSwiftを使用しているとき、subscribe(onNext:)などを使い強参照を防ぐことを目的にしたキャプチャリスト[weak self][hoge]で弱参照にしていることが多いと思います。
その場合、guard letで毎回アンラップして。。と本質の部分とは関係が薄い記述を含んでしまい、冗長なコードになりがちです。
今回紹介するwithUnretained(_:)はそんなオブジェクトの参照を楽にしてくれます。

RxSwift6.0で追加

withUnretained(_:)はRxSwift6.0から追加されたオペレータです。

実際に使ってみます。

// 従来のweak selfを使う場合

hoge
   .subscribe(onNext: { [weak self] _ in
        guard let me = self else { return }
        me.foo.accept(())
}).disposed(by: disposeBag)
// withUnretainedを使う場合

hoge
   .withUnretained(self)
   .subscribe(onNext: { me, _ in
        me.foo.accept(())
}).disposed(by: disposeBag)

このオペレータを使用すると引数で渡したオブジェクトが弱参照のオブジェクトとしてタプル型に追加されます。
こうすることによってguard let ~の部分がそのまま消えスッキリ書くことができるようになります。

withUnretained内部のコードはこちらになっています。↓

    public func withUnretained<Object: AnyObject, Out>(
        _ obj: Object,
        resultSelector: @escaping (Object, Element) -> Out
    ) -> Observable<Out> {
        map { [weak obj] element -> Out in
            guard let obj = obj else { throw UnretainedError.failedRetaining }

            return resultSelector(obj, element)
        }
        .catch{ error -> Observable<Out> in
            guard let unretainedError = error as? UnretainedError,
                  unretainedError == .failedRetaining else {
                return .error(error)
            }

            return .empty()
        }
    }

error処理を内部で書いてくれているので、自分でelse { return 〇〇 }の型を考える必要も無くなりそうですね!

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4