Middle
Quais são os tipos de referências em Swift?
sobes.tech IA
Resposta da IA
Em Swift, existem três tipos principais de referências:
-
**Referência Forte (Strong Reference):
- Aumenta o contador de referências do objeto.
- Impede a desalocação do objeto enquanto existir pelo menos uma referência forte.
- É o tipo padrão de referência em Swift.
- A principal causa de ciclos de referências fortes.
-
**Referência Fraca (Weak Reference):
- Não aumenta o contador de referências.
- Permite a desalocação do objeto se não houver mais referências fortes.
- Declarada usando a palavra-chave
weak. - Sempre é opcional (
Optional), pois o objeto referenciado pode tornar-senil. - Usada para prevenir ciclos de referências fortes, quando uma instância pode existir independentemente de outra.
class Person { let name: String weak var apartment: Apartment? // Referência fraca init(name: String) { self.name = name } deinit { print("\(name) desalocado") } } class Apartment { let unit: String var tenant: Person? // Referência forte normal init(unit: String) { self.unit = unit } deinit { print("Apartamento \(unit) desalocado") } } var john: Person? var unit4A: Apartment? john = Person(name: "John Appleseed") unit4A = Apartment(unit: "4A") john!.apartment = unit4A unit4A!.tenant = john // Aqui surgiria um ciclo de referências fortes sem weak // As referências são anuladas, os objetos são desalocados john = nil unit4A = nil -
**Referência Não Propriedade (Unowned Reference):
- Não aumenta o contador de referências.
- Permite a desalocação do objeto se não houver mais referências fortes.
- Declarada usando a palavra-chave
unowned. - Não é opcional. Assume-se que o objeto referenciado sempre existirá enquanto a instância que contém a referência não própria existir.
- Usar uma referência não própria em um objeto que já foi desalocado causará um erro em tempo de execução (crash).
- Usada para prevenir ciclos de referências fortes, quando uma instância deve sempre existir enquanto outra existir, e não há possibilidade de um deles se tornar
nilindependentemente do outro (por exemplo, em ligaçõesselfem closures).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) desalocado") } } class CreditCard { let number: UInt64 unowned let customer: Customer // Referência não própria init(number: UInt64, customer: Customer) { self.number = number self.customer = customer } deinit { print("Cartão #\(number) desalocado") } } var john: Customer? = Customer(name: "John Appleseed") john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Se o cliente for anulado, o cartão que faz referência a ele com unowned, // tornará inválido, mas não causará ciclo. john = nil // Ambos os objetos são desalocados
A escolha entre weak e unowned depende da natureza da relação entre os objetos: use weak quando um objeto pode existir sem o outro (Person sem Apartment), e unowned quando um objeto sempre deve existir enquanto o outro existir (CreditCard sempre pertence a Customer).