Edited at

RxSwiftでメモリリークを起こさないようにする関数を用意しました。

More than 3 years have passed since last update.

RxSwiftにおいて、mapやflatMapで処理を繋いでいくと、クロージャが結構な数になると思います。

RxSwiftはしっかりとルールを守ることで、クロージャのキャプチャは解放される設計になっていますが、

様々なケースを考えると[weak self]しておくのが、やっぱり安全だったりします。

しかし、毎回weakにするとちょっと面倒ですよね。。

以下のようなコードはよくあると思います。


create { observer in

return NopDisposable.instance
}
.map {
self.~~
}
.map {...}
.map {...}

これをmapの中でweakにすると以下のようになります。


create { observer in

return NopDisposable.instance
}
.map { [weak self] in
guard _self = self else {
throw <# ErrorType #>
}
_self.~~
}
.map {...}

これで全然良いのですが、

毎回書くのはちょっと面倒なので、

以下のグローバル関数を用意しました。

objが取得できなければthrowするというコードです。

extension String: ErrorType {

}

func strong<T>(obj: T?) throws -> T {

guard let obj = obj else {

throw "deallocated"
}

return obj
}

これを利用することで、


create { observer in

return NopDisposable.instance
}
.map { [weak self] in
try strong(self).~~
}
.map {...}

という感じで短く書けるようになりました。

毎回これを必ず使用するというわけではありませんが、

selfのキャプチャが多く、心配なときに利用していこうと思っています。

チームでの開発においては、基本にweakにするとかルールを決めてしまったほうが、

考えるコストを削減出来るメリットもありそうです。

以上、RxSwiftというよりかは、Swiftのクロージャについてのtipsでした。

ちょっとした宣伝ですが、

Filという写真編集アプリを開発しています。

是非使ってみてください😇

Fil - App Store-