Middle
¿Qué tipos de enlaces existen en Swift?
sobes.tech AI
Respuesta de la IA
En Swift, existen tres tipos principales de referencias a instancias de clases:
-
Referencia fuerte (Strong Reference):
- Es el tipo de referencia por defecto.
- La referencia fuerte incrementa el contador de referencias del objeto.
- El objeto no será liberado de la memoria mientras exista al menos una referencia fuerte.
- La causa principal de fugas de memoria en ciclos de referencias fuertes (
strong reference cycles).
class Person { let name: String init(name: String) { self.name = name } deinit { print("\(name) está siendo destruido") } } var reference1: Person? = Person(name: "John") // reference1 ahora es una referencia fuerte, el contador de referencias de Person aumenta -
Referencia débil (Weak Reference):
- Se declara usando la palabra clave
weak. - La referencia débil no incrementa el contador de referencias del objeto.
- Se usa para prevenir ciclos de referencias fuertes (
strong reference cycles). - Siempre es opcional (
Optional), porque el objeto al que apunta la referencia débil puede ser destruido en cualquier momento. Cuando el objeto se destruye, la referencia débil automáticamente se vuelvenil.
class Apartment { let unit: String weak var tenant: Person? // Referencia débil init(unit: String) { self.unit = unit } deinit { print("Apartamento \(unit) está siendo destruido") } } var john: Person? = Person(name: "John") var unit4A: Apartment? = Apartment(unit: "4A") john?.apartment = unit4A // Si Apartment tuviera una referencia fuerte a Person unit4A?.tenant = john // Referencia débil // Después de eliminar las referencias fuertes, los objetos serán destruidos john = nil unit4A = nil // Salida: "John está siendo destruido", "Apartamento 4A está siendo destruido" // Si tenant fuera una referencia fuerte, ocurriría una fuga de memoria (ciclo fuerte) - Se declara usando la palabra clave
-
Referencia no poseída (Unowned Reference):
- Se declara usando la palabra clave
unowned. - Similar a la referencia débil, no incrementa el contador de referencias del objeto.
- También se usa para prevenir ciclos de referencias fuertes.
- A diferencia de
weak, no es opcional (Optional) y supone que el objeto al que apunta existirá durante toda la "vida" de la referencia no poseída. - Si el objeto al que apunta la referencia
unownedse destruye antes de que la referenciaunownedsea inválida, ocurrirá un error en tiempo de ejecución (runtime error). - Es adecuada en situaciones donde un objeto siempre existe mientras otro objeto relacionado también exista (por ejemplo, "padre-hijo", donde el padre posee al hijo, pero el hijo no posee al padre de forma fuerte).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) está siendo destruido") } } class CreditCard { let number: Int unowned let customer: Customer // Referencia no poseída init(number: Int, customer: Customer) { self.number = number self.customer = customer // Asignación segura en init } deinit { print("Tarjeta #\(number) está siendo destruida") } } var john: Customer? = Customer(name: "John Doe") john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Eliminar la referencia fuerte a Customer john = nil // Salida: "John Doe está siendo destruido", "Tarjeta #1234567890123456 está siendo destruida" // La referencia no poseída en CreditCard fue válida mientras existía customer. // Si CreditCard durara más que Customer y se intentara acceder a customer a través de la referencia no poseída, ocurriría un error. - Se declara usando la palabra clave
Diferencia clave entre weak y unowned:
weak: el objeto puede sernil. Úselo cuando la duración de los objetos no esté estrictamente relacionada (uno puede existir sin el otro).unowned: el objeto no puede sernildespués de la inicialización. Úselo cuando esté seguro de que el objeto referenciado existirá al menos hasta que exista el objeto que hace referencia a él.