Middle
¿Qué tipos de enlaces existen en Swift?
sobes.tech AI
Respuesta de la IA
En Swift, existen tres tipos principales de referencias:
-
Referencia Fuerte (Strong Reference):
- Aumenta el contador de referencias del objeto.
- Previene la desasignación del objeto mientras exista al menos una referencia fuerte.
- Es el tipo de referencia por defecto en Swift.
- La causa principal de ciclos de referencias fuertes.
-
**Referencia Débil (Weak Reference):
- No aumenta el contador de referencias.
- Permite la desasignación del objeto si ya no hay referencias fuertes.
- Se declara usando la palabra clave
weak. - Siempre es opcional (
Optional), ya que el objeto referenciado puede sernil. - Se usa para prevenir ciclos de referencias fuertes, cuando una instancia puede existir independientemente de otra.
class Person { let name: String weak var apartment: Apartment? // Referencia débil init(name: String) { self.name = name } deinit { print("\(name) desasignado") } } class Apartment { let unit: String var tenant: Person? // Referencia fuerte normal init(unit: String) { self.unit = unit } deinit { print("Apartamento \(unit) desasignado") } } var john: Person? var unit4A: Apartment? john = Person(name: "John Appleseed") unit4A = Apartment(unit: "4A") john!.apartment = unit4A unit4A!.tenant = john // Aquí surgiría un ciclo de referencias fuertes sin weak // Las referencias se anulan, los objetos se desasignan john = nil unit4A = nil -
**Referencia No Propia (Unowned Reference):
- No aumenta el contador de referencias.
- Permite la desasignación del objeto si ya no hay referencias fuertes.
- Se declara usando la palabra clave
unowned. - No es opcional. Se asume que el objeto referenciado siempre existirá mientras exista la instancia que contiene la referencia no propia.
- Usar una referencia no propia en un objeto que ya fue desasignado causará un error en tiempo de ejecución (crash).
- Se usa para prevenir ciclos de referencias fuertes, cuando una instancia siempre debe existir mientras otra exista, y no hay posibilidad de que uno sea
nilindependientemente del otro (por ejemplo, en enlacesselfen cierres).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) desasignado") } } class CreditCard { let number: UInt64 unowned let customer: Customer // Referencia no propia init(number: UInt64, customer: Customer) { self.number = number self.customer = customer } deinit { print("Tarjeta #\(number) desasignada") } } var john: Customer? = Customer(name: "John Appleseed") john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Si se anula el cliente, la tarjeta que hace referencia a él con unowned, // se volverá inválida, pero no causará ciclo. john = nil // Ambos objetos se desasignan
La elección entre weak y unowned depende de la naturaleza de la relación entre los objetos: usa weak cuando un objeto puede existir sin el otro (Person sin Apartment), y unowned cuando un objeto siempre debe existir mientras exista el otro (CreditCard siempre pertenece a Customer).