RXSwift subscribeNextクロージャー内で[weak self]
を使用する必要がありますか?
私はコードを持っています:
searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { searchText in
self.viewModel.searchForLocation(searchText)
}.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)
クロージャの最初に[weak self]
キャプチャリストがあるように変更する必要がありますか?このような:
searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { [weak self] searchText in
self?.viewModel.searchForLocation(searchText)
}.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)
クロージャがクラスによって所有されていない場合、[weak self]
を使用する必要はありません。
インラインクロージャの場合、クロージャはクラスによって所有されているのではなく、クラスが属するスコープによって所有されており、スコープが終了すると解放されます。
クロージャが渡された場合、クラス(たとえばプロパティ)が所有している場合と所有していない場合があり、クラスが所有している場合は[weak self]
を使用するのが賢明です。
はい、クロージャ内でself
にアクセスし、クロージャが呼び出される前にself
がself
になる可能性がある場合、nil
の弱いキャプチャを作成する必要があります。
クロージャがself
をキャプチャし、self
がnil
になった場合、クロージャが呼び出されてそのself
にアクセスしようとすると、例外が発生します。
Scottegの功績により、彼はGitHubにサンプルプロジェクトを用意しています。 https://github.com/scotteg/TestRxSwiftClosures
例のDetailViewController
を参照してください。
他の2つの例のコメントを一度に1つずつ解除して、結果を確認できます。最初のものはキャプチャリストをまったく定義せず、2番目のものはunowned
キャプチャを定義します。アプリを実行し、テキストを入力して、5秒以内に[完了]をタップします(閉鎖ごとに5秒の遅延があります)。最初の2つの例では、例外がスローされます。
基本的なルールは次のとおりです。たとえば、参照するインスタンスの割り当てが解除されるなど、キャプチャ(self
など)をnil
に設定できる場合は、キャプチャをweak
として定義します。それ以外の場合、クロージャとそのクロージャ内のキャプチャが常にalwaysを参照し、同時に割り当て解除される場合は、キャプチャをunowned
として定義します。
強力な参照サイクルがある場合は、[unowned self]
または[weak self]
を使用する必要があります。クロージャー内の変数は、クロージャーによって「所有」され、クロージャーが存在する場合は固定されます。そのため、[unowned self]
または[weak self]
を実行します。