Подтвердить что ты не робот

"Слабое я" в закрытии RXSwift

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

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

    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)
4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

См. DetailViewController в этом примере.

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

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

Ответ 3

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