2016-01-25 12 views
22

RXSwiftのsubscribeNext閉鎖内で[weak self]を使用する必要がありますか?RXSwift閉鎖の[弱い自己] '

私は、コードを持っている:閉鎖の先頭に[weak self]キャプチャリストがあるよう

searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { searchText in 
     self.viewModel.searchForLocation(searchText) 
    }.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag) 

は、私はそれを修正する必要がありますか?このように:

searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { [weak self] searchText in 
     self?.viewModel.searchForLocation(searchText) 
    }.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag) 
+0

どのように自分をキャプチャしたいのかによって、弱く強くなります。弱いのは、保持サイクルを破るという利点がありますが... – Cristik

答えて

11

クロージャがクラスによって所有されていない場合は、[weak self]を使用する必要はありません。

インラインクロージャの場合、クロージャはクラスによって所有されていませんが、クロージャはそのスコープによって所有され、スコープが残されたときに解放されます。

クロージャーが渡された場合、それはクラスによって所有されている場合と所有されていない場合があります(例:プロパティ)。[weak self]を使用することが賢明です。

+1

あなたの答えはちょっと混乱します。クロージャがスコープ(例えば、関数)によって所有されていた場合、クロージャは、その関数が呼び出された後に決して呼び出されない。クロージャはあなたが観測しているオブジェクトによって所有されています。その場合は 'searchBar'です。だから何とか 'self'が' searchBar'への強い参照を持っているならOPは 'weak'を使うべきです – streem

0

あなたは強い参照サイクルがあるかどうか[unowned self][weak self]を使用したいと思います。閉包内の変数は閉包によって「所有」することができ、閉包がある場合にはそれに固執するので、[unowned self]または[weak self]の理由があります。

6

クロージャ内でselfにアクセスすると弱いキャプチャを作成し、クロージャが呼び出される前にselfnilになる可能性があります。

クロージャーがselfをキャプチャしてからselfnilになると、クロージャーが呼び出され、そのクロージャーがselfにアクセスしようとすると例外が発生します。 scottegする

クレジットは、彼がGitHubの上のサンプルプロジェクトがあります。https://github.com/scotteg/TestRxSwiftClosures

は一例でDetailViewControllerを参照してください。

他の2つの例のコメントを解除して、結果を確認することができます。最初のキャプチャリストはキャプチャリストをまったく定義しません。もう1つはキャプチャリストを定義します(unowned)。アプリを実行してテキストを入力し、5秒以内に[完了]をタップします(各クロージャに5秒の遅延があります)。最初の2つの例では、例外がスローされます。

基本的なルールは次のとおりです。キャプチャ(たとえば、self)をnilに設定できる場合(参照するインスタンスが割り当て解除された場合など)は、キャプチャをweakと定義します。そうでない場合、そのクロージャ内のクロージャとキャプチャがとなる場合は、常にが参照され、同時に割り付け解除される場合は、キャプチャをunownedと定義します。

関連する問題