As referências weak
e unowned
não criam uma strong
retenção no objeto referido (também conhecido como não aumentam a contagem de retenção para impedir que o ARC desaloque o objeto referido).
Mas por que duas palavras-chave? Essa distinção tem a ver com o fato de os Optional
tipos serem integrados na linguagem Swift. Para encurtar a história: tipos opcionais oferecem segurança à memória (isso funciona muito bem com as regras de construtor de Swift - que são rígidas para fornecer esse benefício).
Uma weak
referência permite a possibilidade de se tornar nil
(isso acontece automaticamente quando o objeto referenciado é desalocado); portanto, o tipo de sua propriedade deve ser opcional - para que você, como programador, seja obrigado a verificá-la antes de usá-lo (basicamente o O compilador obriga você, na medida do possível, a escrever um código seguro).
Uma unowned
referência presume que nunca se tornará nil
durante sua vida útil. Uma referência não proprietária deve ser definida durante a inicialização - isso significa que a referência será definida como um tipo não opcional que pode ser usado com segurança sem verificações. Se, de alguma forma, o objeto que está sendo referido for desalocado, o aplicativo falhará quando a referência não proprietária for usada.
Dos documentos da Apple :
Use uma referência fraca sempre que for válido que essa referência se torne nula em algum momento durante sua vida útil. Por outro lado, use uma referência não proprietária quando souber que a referência nunca será nula depois de definida durante a inicialização.
Nos documentos, existem alguns exemplos que discutem ciclos de retenção e como quebrá-los. Todos esses exemplos são extraídos dos documentos .
Exemplo da weak
palavra-chave:
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
weak var tenant: Person?
}
E agora, para algumas obras de arte ASCII (você deve consultar os documentos - eles têm belos diagramas):
Person ===(strong)==> Apartment
Person <==(weak)===== Apartment
O exemplo Person
e Apartment
mostra uma situação em que duas propriedades, que são permitidas nulas, têm o potencial de causar um forte ciclo de referência. Este cenário é melhor resolvido com uma referência fraca. Ambas as entidades podem existir sem ter uma dependência estrita da outra.
Exemplo da unowned
palavra-chave:
class Customer {
let name: String
var card: CreditCard?
init(name: String) { self.name = name }
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) { self.number = number; self.customer = customer }
}
Neste exemplo, a Customer
pode ou não ter a CreditCard
, mas a CreditCard
sempre será associado a a Customer
. Para representar isso, a Customer
classe possui uma card
propriedade opcional , mas a CreditCard
classe possui uma propriedade não opcional (e não proprietária) customer
.
Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard
O exemplo Customer
e CreditCard
mostra uma situação em que uma propriedade que pode ser nula e outra que não pode ser nula têm o potencial de causar um forte ciclo de referência. Este cenário é melhor resolvido com uma referência não proprietária.
Nota da Apple:
Referências fracas devem ser declaradas como variáveis, para indicar que seu valor pode mudar em tempo de execução. Uma referência fraca não pode ser declarada como constante.
Há também um terceiro cenário em que ambas as propriedades devem sempre ter um valor e nenhuma deve ser nula depois que a inicialização estiver concluída.
E também há os cenários clássicos de ciclo de retenção a serem evitados ao trabalhar com fechamentos.
Para isso, recomendo que você visite os documentos da Apple ou leia o livro .