Swift tiene:
- Referencias fuertes
- Referencias débiles
- Referencias sin propietario
¿En qué se diferencia una referencia no propiedad de una referencia débil?
¿Cuándo es seguro usar una referencia no propiedad?
¿Son las referencias no propiedad un riesgo de seguridad como punteros colgantes en C / C ++?
unowned
para las clases que controlamos, para las clases de Apple, usarweak
porque no podemos garantizar con certeza lo que haceRespuestas:
Tanto las referencias
weak
como lasunowned
referencias no crean unastrong
retenció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
Optional
tipos 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
weak
referencia permite la posibilidad de que se conviertanil
(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
unowned
referencia supone que nunca se convertiránil
durante 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 :
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
weak
palabra clave:Y ahora, para algunas ilustraciones ASCII (deberías ir a ver los documentos , tienen diagramas bonitos):
El ejemplo
Person
yApartment
muestra 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
unowned
palabra clave:En este ejemplo, a
Customer
puede o no tener aCreditCard
, pero aCreditCard
siempre estará asociado con aCustomer
. Para representar esto, laCustomer
clase tiene unacard
propiedad opcional , pero laCreditCard
clase tiene una propiedad no opcional (y no propia)customer
.El ejemplo
Customer
yCreditCard
muestra 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:
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 .
fuente
weak var Person?
frentevar Person?
?Q1. ¿En qué se diferencia una "referencia no propiedad" de una "referencia débil"?
Referencia débil:
Referencia sin propietario:
Cuándo usar cada uno:
Q2 ¿Cuándo es seguro usar una "referencia no propiedad"?
Como se citó anteriormente, se supone que una referencia no propiedad siempre tiene un valor. Por lo tanto, solo debe usarlo cuando esté seguro de que la referencia nunca será nula. Los documentos de Apple ilustran un caso de uso para referencias no propiedad a través del siguiente ejemplo.
Supongamos que tenemos dos clases
Customer
yCreditCard
. Un cliente puede existir sin una tarjeta de crédito, pero una tarjeta de crédito no existirá sin un cliente, es decir, se puede suponer que una tarjeta de crédito siempre tendrá un cliente. Entonces, deberían tener la siguiente relación:Q3. ¿Son las referencias de "referencia no propiedad" un riesgo de seguridad como "punteros colgantes" en C / C ++
No lo creo.
Dado que las referencias no propiedad son solo referencias débiles que se garantiza que tienen un valor, no debería ser un riesgo de seguridad de ninguna manera. Sin embargo, si intenta acceder a una referencia no propiedad después de que la instancia a la que hace referencia se desasigna, activará un error de tiempo de ejecución y la aplicación se bloqueará.
Ese es el único riesgo que veo con él.
Enlace a documentos de Apple
fuente
unowned
para la propiedad del padre en la clase hijo. débil es viceversa. Buena explicación @myxtic!unowned
¡las referencias son soloweak
referencias que tienen un valor garantizado!Si el self puede ser nulo en el cierre, use [self débil] .
Si el self nunca será nulo en el cierre, use [self sin dueño] .
Si se bloquea cuando usas [self sin dueño], entonces self probablemente sea nulo en algún momento de ese cierre y probablemente necesites usar [self débil] en su lugar.
Vea los ejemplos sobre el uso de cierres fuertes , débiles y sin dueño en cierres:
https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html
fuente
self
ser nulo?Extractos del enlace
Pocos puntos finales
fuente
Tanto las referencias
weak
como lasunowned
referencias no afectarán el recuento de referencias del objeto. Pero la referencia débil siempre será opcional, es decir, puede ser nula, mientras que lasunowned
referencias nunca pueden ser nulas, por lo que nunca serán opcionales. Cuando use una referencia opcional, siempre tendrá que manejar la posibilidad de que el objeto sea nulo. En caso de una referencia no propiedad, deberá asegurarse de que el objeto nunca sea nulo. Usar una referencia no propiedad de un objeto nulo será similar a desenvolver forzosamente un opcional que sea nulo.Dicho esto, es seguro usar una referencia no propiedad donde esté seguro de que la vida útil del objeto es mayor que la referencia. Si ese no es el caso, es mejor usar una referencia débil en su lugar.
En cuanto a la tercera parte de la pregunta, no creo que la referencia no propiedad sea similar a un puntero colgante. Cuando hablamos del recuento de referencia, generalmente nos referimos al recuento de referencia fuerte del objeto. De manera similar, swift mantiene el recuento de referencias no deseadas y los recuentos de referencias débiles para el objeto (los puntos de referencia débiles a algo llamado "tabla lateral" en lugar del objeto mismo). Cuando el recuento de referencia fuerte llega a cero, el objeto se desinicializa, pero no se puede desasignar si el recuento de referencia no propiedad es mayor que cero.
Ahora, un puntero colgante es algo que apunta a una ubicación de memoria que ya ha sido desasignada. Pero con rapidez, dado que la memoria solo se puede desasignar mientras exista una referencia no deseada al objeto, no puede causar un puntero colgante.
Hay muchos artículos que analizan la administración rápida de memoria con más detalle. Aquí hay uno.
fuente
Las referencias no propiedad son un tipo de referencia débil utilizada en el caso de una relación del mismo tiempo de vida entre dos objetos, cuando un objeto solo debe ser propiedad de otro objeto. Es una forma de crear un enlace inmutable entre un objeto y una de sus propiedades.
En el ejemplo dado en el video intermedio rápido de WWDC, una persona posee una tarjeta de crédito, y una tarjeta de crédito solo puede tener un titular. En la tarjeta de crédito, la persona no debe ser una propiedad opcional, ya que no desea tener una tarjeta de crédito flotando con un solo propietario. Puede romper este ciclo haciendo que la propiedad del titular del crédito sea una referencia débil, pero eso también requiere que lo haga opcional y variable (en lugar de constante). La referencia no propiedad en este caso significa que aunque CreditCard no tiene una participación en una Persona, su vida depende de ello.
fuente
Úselo
unowned
cuando esté seguro deself
que nunca puede estarnil
en el punto de accesoself
en ese punto.Ejemplo (por supuesto, puede agregar el objetivo directamente
MyViewController
, pero de nuevo, es un ejemplo simple):Úselo
weak
cuando existe la posibilidad de queself
pueda estarnil
en el punto de accesoself
.Ejemplo:
Contras de
unowned
:Contras de
weak
:Si no estás seguro, úsalo
weak
. ¡Espere , quiero decir, pregunte aquí en StackOverflow qué debe hacer en su caso! Usar débil todo el tiempo cuando no deberías es solo confuso para ti y para el lector de tu código.fuente