Dois-je utiliser [weak self]
dans RXSwift subscribeNext fermetures?
J'ai le code:
searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { searchText in
self.viewModel.searchForLocation(searchText)
}.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)
Dois-je le modifier pour qu'il y ait un [weak self]
liste de capture au début de la fermeture? Comme ça:
searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { [weak self] searchText in
self?.viewModel.searchForLocation(searchText)
}.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)
Si la fermeture n'appartient pas à la classe, vous n'avez pas besoin d'utiliser [weak self]
.
Dans le cas de fermetures en ligne, la fermeture n'appartient pas à la classe mais à l'étendue dans laquelle elle se trouve et sera libérée lorsque l'étendue sera laissée.
Si la fermeture est passée, elle peut appartenir ou non à la classe (une propriété par exemple) et il est prudent d'utiliser [weak self]
au cas où il appartient à la classe.
Oui, vous devez créer une capture faible de self
si vous accédez à self
dans la fermeture et il est possible que self
devienne nil
avant la fermeture. appelé.
Si une fermeture capture self
puis self
devient nil
, lorsque la fermeture est appelée et tente d'accéder à cette self
, vous obtenez une exception.
Crédit à scotteg, il a un exemple de projet sur GitHub: https://github.com/scotteg/TestRxSwiftClosures
Voir DetailViewController
dans l'exemple.
Vous pouvez décommenter les deux autres exemples, un à la fois, pour voir les résultats. La première ne définit pas du tout de liste de capture et la seconde définit une capture unowned
. Exécutez l'application et entrez du texte et appuyez sur Terminé dans les 5 secondes (il y a un délai de 5 secondes dans chaque fermeture). Les deux premiers exemples entraîneront la levée d'exceptions.
La règle de base est la suivante: si la capture (par exemple, self
) peut être définie sur nil
, comme si l'instance à laquelle elle fait référence est désallouée, définissez la capture comme weak
. Sinon, si une fermeture et une capture à l'intérieur de cette fermeture se réfèrent toujours et se désallouent en même temps, définissez la capture comme unowned
.
Vous voudrez utiliser [unowned self]
ou [weak self]
s'il y aura un cycle de référence fort. Les variables à l'intérieur des fermetures peuvent être "possédées" par la fermeture et resteront si la fermeture est, c'est pourquoi nous faisons [unowned self]
ou [weak self]
.