''[yo débil]'' en los cierres de RXSwift
closures rx-swift (3)
¿Necesito usar [weak self]
dentro de RXSwift subscribeNext closures?
Tengo el codigo
searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { searchText in
self.viewModel.searchForLocation(searchText)
}.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)
¿Necesito modificarlo para que haya una lista de captura [weak self]
al comienzo del cierre? Me gusta esto:
searchController.searchBar.rx_text.throttle(0.2, scheduler: MainScheduler.instance).subscribeNext { [weak self] searchText in
self?.viewModel.searchForLocation(searchText)
}.addDisposableTo(DisposelBag.sharedDisposelBag.disposeBag)
Sí, debes crear una débil captura de ti self
si accedes a ti self
dentro del cierre y es posible que el self
pueda volverse nil
antes de que se llame el cierre.
Si un cierre se captura a self
y luego el self
vuelve nil
, cuando se llama al cierre e intenta acceder a ese self
, obtendrá una excepción.
Gracias a scotteg, tiene un proyecto de ejemplo en GitHub: https://github.com/scotteg/TestRxSwiftClosures
Ver el DetailViewController
en el ejemplo.
Puede descomentar los otros dos ejemplos, uno a la vez, para ver los resultados. El primero no define una lista de captura en absoluto, y el segundo define una captura unowned
. Ejecute la aplicación, ingrese texto y toque Hecho en 5 segundos (hay un retraso de 5 segundos en cada cierre). Los dos primeros ejemplos darán lugar a que se produzcan excepciones.
La regla básica es esta: si la captura (por ejemplo, self
) se puede establecer en nil
, como si la instancia a la que hace referencia se desasigna, defina la captura como weak
. De lo contrario, si un cierre y una captura dentro de ese cierre siempre se referirán entre sí y se desasignarán al mismo tiempo, defina la captura como unowned
.
Si el cierre no es propiedad de la clase, no tiene que usar [weak self]
.
En el caso de cierres en línea, el cierre no es propiedad de la clase, sino por el alcance en el que se encuentra y se liberará cuando se deje el alcance.
Si se pasa el cierre, puede o no ser propiedad de la clase (una propiedad, por ejemplo) y es prudente usar [weak self]
caso de que sea de la clase.
[unowned self]
usar [unowned self]
o [weak self]
si habrá un ciclo de referencia fuerte. Las variables dentro de los cierres pueden ser "propiedad" del cierre y se mantendrán alrededor si es el cierre, por lo que hacemos [unowned self]
o [weak self]
.