2016-01-25 15 views
22

Czy potrzebuję użyć [weak self] w ramach subskrypcji RXSwiftNastępne zamknięcia?"[słabe samo]" w zamknięciach RXSwift

mam kod:

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

Czy muszę go zmodyfikować tak, że istnieje lista [weak self] uchwycenia na początku zamknięcia? Tak:

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

Zależy od tego, jak chcesz uchwycić siebie: słabo lub mocno. Słaba ma tę zaletę, że łamie cykle zatrzymania, ale ... – Cristik

Odpowiedz

11

Jeśli zamknięcie nie należy do klasy, nie musisz używać numeru [weak self].

W przypadku zamknięć w linii zamknięcie nie jest własnością klasy, ale jest objęte zakresem i zostanie zwolnione po opuszczeniu zakresu.

Jeśli zamknięcie zostanie przekazane, może należeć do klasy (np. Własność) i rozsądnie jest używać [weak self], jeśli jest własnością tej klasy.

+1

Twoja odpowiedź jest nieco myląca. Jeśli zamknięcie było własnością zakresu, np. Funkcji, zamknięcie nigdy nie zostanie wywołane po wywołaniu tej funkcji. Zamknięcie jest własnością obserwowanego obiektu, w tym przypadku 'searchbar". Więc jeśli w jakiś sposób 'self' ma silne odniesienie do' searchBar' OP powinien używać 'słabego' – streem

0

Będziemy chcieli wykorzystać [unowned self] lub [weak self] jeśli będzie silny cykl odniesienia. Zmienne wewnątrz zamknięć mogą być "posiadane" przez zamknięcie i będą się trzymać, jeśli zamknięcie jest, dlatego robimy [unowned self] lub [weak self].

6

Tak, należy utworzyć słabe przechwytywanie self, jeśli uzyskasz dostęp do self w ramach zamknięcia i możliwe jest, że self może stać się nil przed wywołaniem zamknięcia.

Jeśli zamknięcie przechwyci numer self, a następnie self stanie się nil, po zamknięciu wywołania i próbie dostępu do tego self otrzymasz wyjątek.

zgłosił scotteg, ma przykładowy projekt na GitHub: https://github.com/scotteg/TestRxSwiftClosures

Patrz DetailViewController w przykładzie.

Możesz odkomentować pozostałe dwa przykłady, jeden po drugim, aby zobaczyć wyniki. Pierwszy nie definiuje w ogóle listy przechwytywania, a drugi definiuje przechwycenie unowned. Uruchom aplikację i wprowadź tekst, a następnie wybierz Gotowe w ciągu 5 sekund (w każdym zamknięciu jest 5-sekundowe opóźnienie). Pierwsze dwa przykłady spowodują wyrzucenie wyjątków.

Podstawową zasadą jest to, że: jeśli przechwytywanie (np. self) można ustawić na nil, na przykład jeśli instancja, do której się odwołuje, zostanie zwolniona, zdefiniuj przechwytywanie jako weak. W przeciwnym razie, jeśli zamknięcie i przechwytywanie w obrębie tego zamknięcia będą się zawsze nawiązywać do siebie i będą wzajemnie przydzielane w tym samym czasie, zdefiniuj przechwytywanie jako unowned.