Middle
O que é unowned na linguagem Swift e como é usado?
sobes.tech IA
Resposta da IA
A referência não possuída (gestão indireta fraca) em Swift é usada para evitar ciclos de retenção forte (retain cycles), quando dois objetos referenciam-se mutuamente de forma forte, impedindo a sua libertação de memória.
Características do unowned:
- Garante que o objeto ao qual a referência
unownedse refere existe sempre até ao momento de usar essa referência. - Se tentar aceder à referência
unownedapós o objeto associado ter sido libertado, ocorrerá um erro em tempo de execução (runtime crash). - É usado quando o ciclo de vida do objeto que faz a referência não é mais longo do que o ciclo de vida do objeto ao qual se refere. Ou seja, a referência com
unownednão torna o objeto mais forte.
Exemplo de uso na captura de encerramento:
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit {
print("\(name) está a ser desalojado")
}
}
class CreditCard {
let number: UInt64
unowned let customer: Customer // Referência não possuída a Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit {
print("Cartão #\(number) está a ser desalojado")
}
}
var john: Customer? // Customer opcional para permitir libertação
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
// Atribuir nil a john levará à libertação de Customer e Card,
// pois não há ciclo de retenção forte
john = nil
Outro exemplo - uso de unowned na lista de captura de encerramento:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = { [unowned self] in // Uso de unowned self
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á a ser desalojado")
}
}
var paragraph: HTMLElement? // Elemento HTML opcional
paragraph = HTMLElement(name: "p", text: "olá mundo")
print(paragraph!.asHTML())
// Atribuir nil libertará HTMLElement, pois a clausura não o mantém fortemente
paragraph = nil
A escolha entre unowned e weak depende de se a referência pode ser nil durante a vida do objeto. Se a referência nunca pode tornar-se nil antes da libertação do objeto, use unowned. Se pode, use weak.