sport - Bloquear retener ciclos en Swift?
swift lenguaje (3)
Lo único que me sorprendió con las listas de captura fue cuándo usar débil versus no poseído.
El libro lo destiló a estas reglas:
Si el yo puede ser nulo en el uso de cierre [yo débil].
Si el yo nunca será nulo en el uso de cierre [yo sin dueño].
Consulte la sección Referencias débiles y sin propietario en el libro de Lenguaje de programación Swift para obtener una explicación más detallada.
Tradicionalmente en Objc, hacemos weakSelf para evitar el recuento de retención adicional para los bloques.
¿Cómo gestiona internamente los ciclos retenidos que ocurren en bloques para Objc?
Para evitar que un bloque mantenga una referencia fuerte a un objeto, debe definir una lista de captura para el bloque.
La sintaxis de expresión de cierre se define de la siguiente manera:
{ ( /*parameters*/ ) -> /*return type*/ in
// statements
}
Pero esto se extiende más adelante en la documentación para incluir una lista de captura. Esto efectivamente equivale a la sintaxis de expresión que se define de la siguiente manera:
{ [ /*reference type*/ /*object*/, ... ] ( /*parameters*/ ) -> /*return type*/ in
// statements
}
... donde /*reference type*/
puede ser weak
o unowned
.
La lista de captura es lo primero que aparece en el cierre y es opcional. La sintaxis, como se muestra arriba, se define como uno o más pares de tipos de referencia seguidos por objetos; cada par está separado por una coma. Por ejemplo:
[unowned self, weak otherObject]
Ejemplo completo:
var myClosure = {
[unowned self] in
print(self.description)
}
Tenga en cuenta que una referencia unowned
no es opcional, por lo que no necesita desenvolverla.
Espero eso conteste tu pregunta. Puede leer más sobre ARC en Swift en la sección relevante de la documentación .
Debe prestar especial atención a la diferencia entre weak
y unowned
. Podría ser más seguro en su implementación usar weak
, porque el uso unowned
supone que el objeto nunca será nulo. Esto puede ocasionar que su aplicación se cuelgue si el objeto ha sido desasignado antes de ser utilizado en su cierre.
Usando weak
como el tipo de referencia, ¿deberías desenvolver con ?
, como sigue:
var myClosure = {
[weak self] in
print(self?.description)
}
Como se describió anteriormente, hay 2 posibilidades para evitar retener ciclos en Swift y estos son weak
y unowned
como se describe a continuación:
var sampleClosure = { [unowned self] in
self.doSomething()
}
donde el self
nunca puede ser nil
.
var sampleClosure = { [weak self] in
self?.doSomething()
}
donde el self
necesita ser desenvuelto usando ?
. Aquí hay una observación importante que hacer, si hay más instrucciones que usen uno mismo y puedan compartir los resultados, etc., una posible forma correcta puede ser:
var sampleClosure = { [weak self] in
if let this = self{
this.doSomething()
this.doOtherThings()
}
}
o
var sampleClosure = { [weak self] in
guard let strongSelf = self else{
return
}
strongSelf.doSomething()
strongSelf.doOtherThings()
}