Swift a:
- Références solides
- Références faibles
- Références inconnues
En quoi une référence non possédée est-elle différente d'une référence faible?
Quand est-il sécuritaire d'utiliser une référence sans propriétaire?
Les références non possédées constituent-elles un risque pour la sécurité comme les pointeurs pendants en C / C ++?
swift
memory-management
automatic-ref-counting
weak-references
dangling-pointer
Ian Ringrose
la source
la source
unowned
pour les classes que nous contrôlons, pour les classes Apple, utiliserweak
parce que nous ne pouvons pas garantir avec certitude ce qu'il faitRéponses:
Les références
weak
etunowned
ne créent pas destrong
blocage sur l'objet référencé (c'est-à-dire qu'elles n'augmentent pas le nombre de rétentions afin d'empêcher ARC de désallouer l'objet référencé).Mais pourquoi deux mots-clés? Cette distinction tient au fait que les
Optional
types sont intégrés dans le langage Swift. Longue histoire à leur sujet: les types facultatifs offrent une sécurité de la mémoire (cela fonctionne à merveille avec les règles du constructeur de Swift - qui sont strictes afin de fournir cet avantage).Une
weak
référence permet la possibilité de le devenirnil
(cela se produit automatiquement lorsque l'objet référencé est désalloué), donc le type de votre propriété doit être facultatif - donc vous, en tant que programmeur, êtes obligé de le vérifier avant de l'utiliser (fondamentalement le le compilateur vous force, autant que possible, à écrire du code sûr).Une
unowned
référence suppose qu'elle ne deviendra jamais denil
son vivant. Une référence non possédée doit être définie lors de l'initialisation - cela signifie que la référence sera définie comme un type non facultatif pouvant être utilisé en toute sécurité sans vérification. Si l'objet auquel il est fait référence est désalloué, l'application se bloque lorsque la référence sans propriétaire est utilisée.Depuis les documents Apple :
Dans les documents, il y a quelques exemples qui discutent des cycles de conservation et comment les briser. Tous ces exemples sont extraits de la documentation .
Exemple du
weak
mot - clé:Et maintenant, pour un peu d'art ASCII (vous devriez aller voir les documents - ils ont de jolis diagrammes):
L' exemple
Person
etApartment
montre une situation dans laquelle deux propriétés, toutes deux autorisées à être nulles, ont le potentiel de provoquer un cycle de référence fort. Ce scénario est mieux résolu avec une référence faible. Les deux entités peuvent exister sans dépendre strictement l'une de l'autre.Exemple du
unowned
mot - clé:Dans cet exemple, un
Customer
peut ou non avoir unCreditCard
, mais unCreditCard
sera toujours associé à unCustomer
. Pour représenter cela, laCustomer
classe a unecard
propriété facultative , mais laCreditCard
classe a une propriété non facultative (et sanscustomer
propriétaire ) .L' exemple
Customer
etCreditCard
montre une situation dans laquelle une propriété autorisée à être nulle et une autre propriété qui ne peut pas être nulle ont le potentiel de provoquer un cycle de référence puissant. Ce scénario est mieux résolu avec une référence sans propriétaire.Remarque d'Apple:
Il existe également un troisième scénario où les deux propriétés doivent toujours avoir une valeur, et aucune propriété ne doit jamais être nulle une fois l'initialisation terminée.
Et il existe également les scénarios de cycle de rétention classiques à éviter lorsque vous travaillez avec des fermetures.
Pour cela, je vous encourage à visiter la documentation Apple ou à lire le livre .
la source
weak var Person?
contrevar Person?
?Q1. En quoi une «référence non possédée» est-elle différente d'une «référence faible»?
Référence faible:
Référence sans propriétaire:
Quand utiliser chacun:
Q2. Quand est-il sécuritaire d'utiliser une «référence sans propriétaire»?
Comme indiqué ci-dessus, une référence non possédée est supposée avoir toujours une valeur. Vous ne devez donc l'utiliser que lorsque vous êtes sûr que la référence ne sera jamais nulle. Apple Docs illustre un cas d'utilisation pour les références non possédées à travers l'exemple suivant.
Supposons que nous ayons deux classes
Customer
etCreditCard
. Un client peut exister sans carte de crédit, mais une carte de crédit n'existera pas sans client, c'est-à-dire qu'on peut supposer qu'une carte de crédit aura toujours un client. Ainsi, ils devraient avoir la relation suivante:Q3. Les références «sans référence» constituent-elles un risque pour la sécurité comme les «pointeurs pendants» en C / C ++
Je ne pense pas.
Étant donné que les références non possédées ne sont que des références faibles qui sont garanties d'avoir une valeur, cela ne devrait en aucun cas constituer un risque pour la sécurité. Cependant, si vous essayez d'accéder à une référence non possédée après que l'instance à laquelle elle fait référence est désallouée, vous déclencherez une erreur d'exécution et l'application se bloquera.
C'est le seul risque que je vois avec ça.
Lien vers Apple Docs
la source
unowned
pour la propriété parent dans la classe enfant. faible est vice versa. Belle explication @myxtic!unowned
les références ne sont que desweak
références dont la valeur est garantie!Si le self peut être nul dans la fermeture, utilisez [self faible] .
Si l' auto ne sera jamais nul dans la fermeture, utilisez [auto sans propriétaire] .
S'il se bloque lorsque vous utilisez [auto sans propriétaire], alors self est probablement nul à un moment donné de cette fermeture et vous devez probablement utiliser [self self] à la place.
Découvrez les exemples d'utilisation de fermetures fortes , faibles et sans propriétaire :
https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html
la source
self
être nul?Extraits du lien
Quelques points finaux
la source
Les références
weak
etunowned
n'affecteront pas le nombre de références de l'objet. Mais une référence faible sera toujours facultative, c'est-à-dire qu'elle peut être nulle, alors que lesunowned
références ne peuvent jamais être nulles, elles ne seront donc jamais facultatives. Lorsque vous utilisez une référence facultative, vous devrez toujours gérer la possibilité que l'objet soit nul. En cas de référence non possédée, vous devrez vous assurer que l'objet n'est jamais nul. L'utilisation d'une référence non propriétaire à un objet nil sera similaire à un déballage forcé d'une option nil.Cela dit, il est sûr d'utiliser une référence sans propriétaire où vous êtes sûr que la durée de vie de l'objet est supérieure à celle de la référence. Si ce n'est pas le cas, il vaut mieux utiliser une référence faible à la place.
Quant à la troisième partie de la question, je ne pense pas qu'une référence sans propriétaire soit similaire à un pointeur suspendu. Lorsque nous parlons de comptage de référence, nous nous référons généralement à un comptage de référence fort de l'objet. De même, Swift conserve un nombre de références non possédées et un nombre de références faible pour l'objet (une référence faible pointe vers quelque chose appelé "table d'appoint" plutôt que l'objet lui-même). Lorsque le nombre de références fort atteint zéro, l'objet est réinitialisé, mais il ne peut pas être désalloué si le nombre de références non possédées est supérieur à zéro.
Maintenant, un pointeur suspendu est quelque chose qui pointe vers un emplacement mémoire qui a déjà été désalloué. Mais en un rien de temps puisque la mémoire ne peut être désallouée que tant qu'il y a une référence inconnue à l'objet, elle ne peut pas provoquer un pointeur pendant.
Il existe de nombreux articles qui traitent de la gestion rapide de la mémoire plus en détail. En voici un.
la source
Les références non possédées sont une sorte de référence faible utilisée dans le cas d'une relation à durée de vie identique entre deux objets, lorsqu'un objet ne doit appartenir qu'à un autre objet. C'est un moyen de créer une liaison immuable entre un objet et l'une de ses propriétés.
Dans l'exemple donné dans la vidéo SWDC intermédiaire rapide, une personne possède une carte de crédit, et une carte de crédit ne peut avoir qu'un seul titulaire. Sur la carte de crédit, la personne ne doit pas être une propriété facultative, car vous ne voulez pas qu'une carte de crédit flotte avec un seul propriétaire. Vous pouvez briser ce cycle en faisant de la propriété du titulaire du crédit une référence faible, mais cela vous oblige également à la rendre facultative et variable (par opposition à constante). La référence sans propriétaire dans ce cas signifie que bien que CreditCard ne possède pas de participation dans une personne, sa durée de vie en dépend.
la source
Utilisez
unowned
lorsque vous êtes sûr queself
vous ne pouvez jamais êtrenil
au pointself
auquel vous accédez à ce moment-là.Exemple (vous pouvez bien sûr ajouter la cible directement depuis
MyViewController
, mais encore une fois, c'est un exemple simple):Utiliser
weak
quand il y a une possibilitéself
peut êtrenil
au point auquel vous accédezself
.Exemple:
Contre
unowned
:Contre
weak
:Si vous n'êtes pas sûr, utilisez
weak
. Attendez , je veux dire ici sur StackOverflow ce que vous devez faire dans votre cas! Utiliser faible tout le temps alors que vous ne devriez pas le faire est tout simplement déroutant pour vous et le lecteur de votre code.la source