Je veux juste m'assurer d'avoir bien compris:
__unsafe_unretain
objets que je ne possède pas?__unsafe_unretained
Dois-je utiliser assign
dans le @property
? Cela signifie-t-il que l'objet n'est pas conservé et se réfère simplement à l'objet auquel j'assigne?Le compilateur LLVM 3.0 introduit quatre nouveaux qualificatifs de propriété: __strong
, __autoreleasing
, __unsafe_unretained
, et __weak
. Les trois premiers sont disponibles même en dehors d'ARC, selon la spécification .
Comme Joshua l'indique, par défaut, tous les pointeurs sont supposés être __strong
sous ARC. Cela signifie que lorsqu'un objet est affecté à ce pointeur, il est conservé aussi longtemps que ce pointeur s'y réfère. C'est bien pour la plupart des choses, mais cela ouvre la possibilité de conserver les cycles, comme je le décris dans ma réponse ici . Par exemple, si vous avez un objet qui contient un autre objet en tant que variable d'instance, mais que le deuxième objet a un lien fort vers le premier en tant que délégué, les deux objets ne seront jamais libérés.
C'est pour cette raison que le __unsafe_unretained
et __weak
des qualificatifs existent. Leur utilisation la plus courante est pour les délégués, où vous définiriez une propriété pour ce délégué avec weak
ou unsafe_unretained
attribut (assign
est effectivement unsafe_unretained
), puis faites correspondre cela en marquant la variable d'instance respective avec __weak
ou __unsafe_unretained
. Cela signifie que la variable d'instance déléguée pointera toujours vers le premier objet, mais cela n'entraînera pas la conservation de cet objet, interrompant ainsi le cycle de rétention et autorisant la libération des deux objets.
Au-delà des délégués, cela est utile pour rompre tout autre cycle de rétention qui pourrait se former dans votre code. Utilement, l'instrument Leaks comprend maintenant une vue Cycles, qui montre les cycles de rétention qu'il découvre dans votre application de manière graphique.
Tous les deux __unsafe_unretained
et __weak
empêcher la rétention d'objets, mais de manière légèrement différente. Pour __weak
, le pointeur sur un objet sera converti en nil
sur la désallocation de l'objet vers lequel il pointe, ce qui est un comportement très sûr. Comme son nom l'indique, __unsafe_unretained
continuera de pointer vers la mémoire où se trouvait un objet, même après sa désallocation. Cela peut entraîner des plantages en raison de l'accès à cet objet désalloué.
Pourquoi voudriez-vous utiliser __unsafe_unretained
puis? Malheureusement, __weak
n'est pris en charge que pour iOS 5.0 et Lion en tant que cibles de déploiement. Si vous souhaitez revenir à iOS 4.0 et Snow Leopard, vous devez utiliser le __unsafe_unretained
qualificatif, ou utilisez quelque chose comme Mike Ash MAZeroingWeakRef .
weak
pour les objets qui ne vous appartiennent pas.unsafe_unretained
sur la propriété.unsafe_unretained
les éléments sont comme weak
, sans la sécurité supplémentaire de les effacer lorsque l'élément vers lequel ils pointent est libéré (et les frais généraux qui vont avec).__unsafe_unretained
est identique à ce qu'était le stockage par défaut d'un objet avant ARC. Avec ARC, la valeur par défaut est désormais __strong
ce qui signifie que vous y avez une référence jusqu'à ce que votre référence soit hors de portée.
Une autre observation sur __unsafe_unretained: J'ai des plantages dans mon application sur l'appareil et PAS sur le simulateur avec iVars déclaré __unsafe_unretained! Oui, c'était un bogue dans le code de la migration ARC, mais c'était la première fois que je remarquais une telle différence entre l'appareil et le simulateur.