2016-01-25 4 views
22

Нужно ли мне использовать [weak self] внутри RXSwift subscribeNext закрытия?'[слабый self]' в затворах RXSwift

У меня есть код:

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) 
+0

Зависит от того, как вы хотите захватить себя: слабо или сильно. Слабое имеет преимущество прерывания циклов удержания, хотя ... – Cristik

ответ

11

Если закрытие не принадлежит классу, вам не обязательно использовать [weak self].

В случае замыкания в потоке закрытие не принадлежит классу, но по объему, в котором оно находится, и будет выпущено, когда область остается.

Если закрытое закрыто, оно может принадлежать или не принадлежит классу (например, свойство), и разумно использовать [weak self], если он принадлежит классу.

+1

ваш ответ немного запутан. Если закрытие принадлежало сфере действия, например функции, закрытие никогда не вызывается после вызова этой функции. Закрытие принадлежит объекту, который вы наблюдаете, в этом случае 'searchBar'. Так что, если какой-то «сам» имеет сильное обращение к 'searchBar', OP должен использовать' слабый' – streem

0

Вы хотите использовать [unowned self] или [weak self], если будет сильный опорный цикл. Переменные внутри закрытий могут быть «принадлежащими» закрытием и будут закрываться, если закрытие, поэтому мы делаем [unowned self] или [weak self].

6

Да, вы должны создать слабый захват self, если вы достигнете self в пределах укупорочного средства, и возможно, что self может стать nil до закрытия.

Если замыкание захватывает self и затем self становится nil, когда замыкание называется и пытается получить доступ к этим self, вы получите исключение.

Кредит scotteg, у него есть пример проекта на GitHub: https://github.com/scotteg/TestRxSwiftClosures

ВИДЕТЬ DetailViewController в примере.

Вы можете раскомментировать два других примера, по одному за раз, чтобы увидеть результаты. Первый не определяет список захвата вообще, а второй определяет захват unowned. Запустите приложение и введите текст и нажмите «Готово» в течение 5 секунд (в каждом закрытии есть 5-секундная задержка). Первые два примера приведут к исключению исключений.

Основное правило заключается в следующем: Если захват (например, self) может быть установлен в nil, например, если экземпляр он ссылается будет освобождён, определяют захват в качестве weak. В противном случае, если замыкание и захват в этом закрытии будут всегда ссылаются друг на друга и одновременно освобождаются, определяют захват как unowned.

Смежные вопросы