Tanto las referencias weakcomo las unownedreferencias no crean una strongretención en el objeto referido (es decir, no aumentan el conteo de retención para evitar que ARC desasigne el objeto referido).
¿Pero por qué dos palabras clave? Esta distinción tiene que ver con el hecho de que los Optionaltipos están integrados en el lenguaje Swift. En pocas palabras: los tipos opcionales ofrecen seguridad en la memoria (esto funciona muy bien con las reglas de construcción de Swift, que son estrictas para proporcionar este beneficio).
Una weakreferencia permite la posibilidad de que se convierta nil(esto sucede automáticamente cuando el objeto referenciado se desasigna), por lo tanto, el tipo de su propiedad debe ser opcional, por lo que usted, como programador, está obligado a verificarlo antes de usarlo (básicamente el el compilador lo obliga, tanto como puede, a escribir código seguro).
Una unownedreferencia supone que nunca se convertirá nildurante su vida útil. Se debe establecer una referencia no propia durante la inicialización; esto significa que la referencia se definirá como un tipo no opcional que se puede utilizar de forma segura sin controles. Si de alguna manera el objeto al que se hace referencia se desasigna, la aplicación se bloqueará cuando se use la referencia no propiedad.
De los documentos de Apple :
Utilice una referencia débil siempre que sea válida para que esa referencia sea nula en algún momento durante su vida útil. Por el contrario, use una referencia no propia cuando sepa que la referencia nunca será nula una vez que se haya establecido durante la inicialización.
En los documentos, hay algunos ejemplos que analizan los ciclos de retención y cómo romperlos. Todos estos ejemplos se extraen de los documentos .
Ejemplo de la weakpalabra clave:
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?
}
Y ahora, para algunas ilustraciones ASCII (deberías ir a ver los documentos , tienen diagramas bonitos):
Person ===(strong)==> Apartment
Person <==(weak)===== Apartment
El ejemplo Persony Apartmentmuestra una situación en la que dos propiedades, que pueden ser nulas, tienen el potencial de causar un ciclo de referencia fuerte. Este escenario se resuelve mejor con una referencia débil. Ambas entidades pueden existir sin tener una dependencia estricta de la otra.
Ejemplo de la unownedpalabra clave:
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 }
}
En este ejemplo, a Customerpuede o no tener a CreditCard, pero a CreditCard siempre estará asociado con a Customer. Para representar esto, la Customerclase tiene una cardpropiedad opcional , pero la CreditCardclase tiene una propiedad no opcional (y no propia) customer.
Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard
El ejemplo Customery CreditCardmuestra una situación en la que una propiedad que puede ser nula y otra propiedad que no puede ser nula tiene el potencial de causar un ciclo de referencia fuerte. Este escenario se resuelve mejor con una referencia no propiedad.
Nota de Apple:
Las referencias débiles deben declararse como variables para indicar que su valor puede cambiar en tiempo de ejecución. Una referencia débil no puede declararse como una constante.
También hay un tercer escenario en el que ambas propiedades siempre deben tener un valor, y ninguna de ellas debe ser nula una vez que se complete la inicialización.
Y también están los escenarios clásicos de ciclo de retención para evitar al trabajar con cierres.
Para esto, te animo a que visites los documentos de Apple o leas el libro .