¿En qué consiste la diferencia entre enlaces Wick y enlaces Anound?
sobes.tech AI
Respuesta de la IA
La referencia débil (weak) es una referencia que no posee la propiedad de aumentar el contador de referencias del objeto. Se usa para prevenir ciclos de referencias fuertes, por ejemplo, entre un delegado y su propietario. Si el objeto al que apunta la referencia débil se desasigna, la referencia débil automáticamente se vuelve nil.
La referencia no poseedora (unowned) también es una referencia que no aumenta el contador de referencias del objeto. La diferencia con weak es que unowned no puede ser opcional (Optional) y siempre debe apuntar a un objeto existente. Si el objeto al que apunta la referencia unowned se desasigna antes de que la referencia deje de existir, intentar acceder a esa referencia provocará un error en tiempo de ejecución (error fatal). Se usa donde el ciclo de vida del objeto relacionado es garantizado que sea más largo o igual al ciclo de vida del objeto con la referencia unowned (por ejemplo, en un ciclo de referencias fuertes donde uno de los objetos tiene un ciclo de vida claramente definido).
Comparación:
| Característica | weak |
unowned |
|---|---|---|
| No posee | Sí | Sí |
| Incrementa el conteo | No | No |
Puede ser nil |
Sí (se nulifica automáticamente) | No (debe apuntar a un objeto) |
| Seguridad | Más segura en caso de desasignación | Menos segura (error fatal al acceder a un objeto desasignado) |
| Tipo | Debe ser opcional | No puede ser opcional (por defecto) |
| Uso | Prevención de ciclos de referencias fuertes donde el objeto puede dejar de existir antes | Prevención de ciclos de referencias fuertes donde el objeto garantiza su existencia |
Ejemplo de uso de weak para prevenir ciclos de referencias fuertes:
class Person {
let name: String
weak var apartment: Apartment? // referencia débil para evitar ciclo de retención
init(name: String) {
self.name = name
print("\(name) está siendo inicializado")
}
deinit {
print("\(name) está siendo desinicializado")
}
}
class Apartment {
let unit: String
var occupant: Person?
init(unit: String) {
self.unit = unit
print("Apartamento \(unit) está siendo inicializado")
}
deinit {
print("Apartamento \(unit) está siendo desinicializado")
}
}
Ejemplo de uso de unowned en el contexto de capturar self en un cierre:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in // self no poseedor para evitar ciclo de retención con el cierre
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) está siendo desinicializado")
}
}