Les références weak
et unowned
ne créent pas de strong
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 devenir nil
(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 de nil
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 :
Utilisez une référence faible chaque fois qu'il est valide pour que cette référence devienne nulle à un moment donné au cours de sa durée de vie. Inversement, utilisez une référence non possédée lorsque vous savez que la référence ne sera jamais nulle une fois définie lors de l'initialisation.
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é:
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?
}
Et maintenant, pour un peu d'art ASCII (vous devriez aller voir les documents - ils ont de jolis diagrammes):
Person ===(strong)==> Apartment
Person <==(weak)===== Apartment
L' exemple Person
et Apartment
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é:
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 }
}
Dans cet exemple, un Customer
peut ou non avoir un CreditCard
, mais un CreditCard
sera toujours associé à un Customer
. Pour représenter cela, la Customer
classe a une card
propriété facultative , mais la CreditCard
classe a une propriété non facultative (et sans customer
propriétaire ) .
Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard
L' exemple Customer
et CreditCard
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:
Les références faibles doivent être déclarées en tant que variables, pour indiquer que leur valeur peut changer au moment de l'exécution. Une référence faible ne peut pas être déclarée comme constante.
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 .