Middle
Que tipos de ligações existem em Swift?
sobes.tech IA
Resposta da IA
Em Swift, existem três tipos principais de referências a instâncias de classes:
-
Referência forte (Strong Reference):
- É o tipo padrão de referência.
- A referência forte aumenta o contador de referências do objeto.
- O objeto não será liberado da memória enquanto existir pelo menos uma referência forte.
- A principal causa de vazamentos de memória em ciclos de referências fortes (
strong reference cycles).
class Person { let name: String init(name: String) { self.name = name } deinit { print("\(name) está sendo desinicializado") } } var reference1: Person? = Person(name: "John") // reference1 agora é uma referência forte, o contador de referências de Person aumenta -
Referência fraca (Weak Reference):
- Declarada usando a palavra-chave
weak. - A referência fraca não aumenta o contador de referências do objeto.
- Usada para prevenir ciclos de referências fortes (
strong reference cycles). - Sempre é opcional (
Optional), porque o objeto apontado pela referência fraca pode ser destruído a qualquer momento. Quando o objeto é destruído, a referência fraca automaticamente se tornanil.
class Apartment { let unit: String weak var tenant: Person? // Referência fraca init(unit: String) { self.unit = unit } deinit { print("Apartamento \(unit) está sendo desinicializado") } } var john: Person? = Person(name: "John") var unit4A: Apartment? = Apartment(unit: "4A") john?.apartment = unit4A // Se Apartment tivesse uma referência forte a Person unit4A?.tenant = john // Referência fraca // Após remover as referências fortes, os objetos serão desinicializados john = nil unit4A = nil // Saída: "John está sendo desinicializado", "Apartamento 4A está sendo desinicializado" // Se tenant fosse uma referência forte, ocorreria uma fuga de memória (cycle forte) - Declarada usando a palavra-chave
-
Referência não possuída (Unowned Reference):
- Declarada usando a palavra-chave
unowned. - Semelhante à referência fraca, não aumenta o contador de referências do objeto.
- Também usada para prevenir ciclos de referências fortes.
- Ao contrário de
weak, não é opcional (Optional) e supõe que o objeto ao qual ela aponta existirá durante toda a "vida" da referência não possuída. - Se o objeto ao qual a referência
unownedaponta for destruído antes que a referênciaunownedse torne inválida, ocorrerá um erro em tempo de execução (runtime error). - Adequada para situações onde um objeto sempre existe enquanto outro objeto relacionado também exista (por exemplo, "pai-filho", onde o pai possui o filho, mas o filho não possui o pai de forma forte).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) está sendo desinicializado") } } class CreditCard { let number: Int unowned let customer: Customer // Referência não possuída init(number: Int, customer: Customer) { self.number = number self.customer = customer // Atribuição segura em init } deinit { print("Cartão #\(number) está sendo desinicializado") } } var john: Customer? = Customer(name: "John Doe") john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Remover a referência forte a Customer john = nil // Saída: "John Doe está sendo desinicializado", "Cartão #1234567890123456 está sendo desinicializado" // A referência não possuída em CreditCard era válida enquanto customer existia. // Se CreditCard durasse mais que Customer e tentássemos acessar customer através da referência não possuída, ocorreria um erro. - Declarada usando a palavra-chave
Diferença chave entre weak e unowned:
weak: o objeto pode sernil. Use quando a duração de vida dos objetos não estiver estritamente relacionada (um pode existir sem o outro).unowned: o objeto não pode sernilapós a inicialização. Use quando tiver certeza de que o objeto referenciado existirá pelo menos até que o objeto que faz referência a ele exista.