Qual é a diferença entre links Wick e links Anound?
sobes.tech IA
Resposta da IA
A referência fraca (weak) é uma referência que não possui o controle do contador de referências do objeto. É usada para evitar ciclos de referências fortes, por exemplo, entre um delegado e seu proprietário. Se o objeto apontado pela referência fraca for desalocado, a referência fraca torna-se automaticamente nil.
A referência não possuída (unowned) também é uma referência que não aumenta o contador de referências do objeto. A diferença com weak é que unowned não pode ser opcional (Optional) e deve sempre apontar para um objeto existente. Se o objeto apontado pela referência unowned for desalocado antes que a referência deixe de existir, uma tentativa de acesso a essa referência resultará em um erro de execução (erro fatal). É usada onde o ciclo de vida do objeto relacionado é garantido que seja mais longo ou igual ao ciclo de vida do objeto com a referência unowned (por exemplo, em um ciclo de referências fortes onde um dos objetos tem um ciclo de vida claramente definido).
Comparação:
| Característica | weak |
unowned |
|---|---|---|
| Não possui | Sim | Sim |
| Incrementa o SC | Não | Não |
Pode ser nil |
Sim (é automaticamente nulificado) | Não (deve apontar para um objeto) |
| Segurança | Mais segura em caso de desalocação | Menos segura (erro fatal ao acessar um objeto desalocado) |
| Tipo | Deve ser opcional | Não pode ser opcional (padrão) |
| Uso | Prevenir ciclos de referências fortes onde o objeto pode deixar de existir antes | Prevenir ciclos de referências fortes onde o objeto garante sua existência |
Exemplo de uso de weak para prevenir ciclo de referências fortes:
class Person {
let name: String
weak var apartment: Apartment? // referência fraca para evitar ciclo de retenção
init(name: String) {
self.name = name
print("\(name) está sendo inicializado")
}
deinit {
print("\(name) está sendo desinicializado")
}
}
class Apartment {
let unit: String
var occupant: Person?
init(unit: String) {
self.unit = unit
print("Apartamento \(unit) está sendo inicializado")
}
deinit {
print("Apartamento \(unit) está sendo desinicializado")
}
}
Exemplo de uso de unowned no contexto de capturar self em uma closure:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in // unowned self para evitar ciclo de retenção com a closure
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á sendo desinicializado")
}
}