はじめに
本記事では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 〇〇 }の型を考える必要も無くなりそうですね!