J'essaye de terminer le puzzle.
__strong
est la valeur par défaut pour tous les pointeurs d'objet conservables Objective-C comme NSObject, NSString, etc. C'est une référence forte. ARC équilibre avec un -release
à la fin de la portée.
__unsafe_unretained
équivaut à l'ancienne. Il est utilisé pour un pointeur faible sans conserver l'objet pouvant être conservé.
__weak
est comme __unsafe_unretained
sauf que c'est une référence faible à mise à zéro automatique, ce qui signifie que le pointeur sera mis à nil dès que l'objet référencé sera libéré. Cela élimine le risque de pointeurs suspendus et d'erreurs EXC_BAD_ACCESS.
Mais à quoi sert exactement __autoreleasing
? J'ai du mal à trouver des exemples pratiques sur le moment où je dois utiliser ce qualificatif. Je pense que ce n'est que pour les fonctions et les méthodes qui attendent un pointeur-pointeur tel que:
- (BOOL)save:(NSError**);
ou
NSError *error = nil;
[database save:&error];
qui sous ARC doit être déclaré de cette façon:
- (BOOL)save:(NSError* __autoreleasing *);
Mais c'est trop vague et j'aimerais bien comprendre pourquoi . Les extraits de code que je trouve placent le __autoreleasing entre les deux étoiles, ce qui me semble bizarre. Le type est NSError**
(un pointeur-pointeur vers NSError), alors pourquoi placer __autoreleasing
entre les étoiles et pas simplement devant NSError**
?
De plus, il peut y avoir d'autres situations sur lesquelles je dois me fier __autoreleasing
.
la source
Réponses:
Vous avez raison. Comme l'explique la documentation officielle:
Tout cela est très bien expliqué dans le guide de transition ARC .
Dans votre exemple NSError, la déclaration signifie
__strong
, implicitement:Sera transformé en:
Lorsque vous appelez votre
save
méthode:Le compilateur devra alors créer une variable temporaire, définie à
__autoreleasing
. Alors:Sera transformé en:
Vous pouvez éviter cela en déclarant
__autoreleasing
directement l' objet d'erreur .la source
__autoreleasing
n'est utilisé que pour les arguments passés par référence. C'est un cas particulier, car vous avez un pointeur vers le pointeur d'un objet. Ce n'est pas le cas avec des éléments tels que les constructeurs de commodité, car ils ne renvoient qu'un pointeur vers un objet, et comme ARC le gère automatiquement.Suite à la réponse de Macmade et à la question de suivi du membre fier dans les commentaires, (l'aurait également posté sous forme de commentaire mais cela dépasse le nombre maximal de caractères):
Voici pourquoi le qualificatif variable de __autoreleasing est placé entre les deux étoiles.
Pour commencer, la syntaxe correcte pour déclarer un pointeur d'objet avec un qualificatif est:
Le compilateur vous pardonnera ceci:
mais ce n'est pas correct. Consultez le guide de transition Apple ARC (lisez la section qui commence «Vous devez décorer correctement les variables ...»).
Pour répondre à la question en cours: un double pointeur ne peut pas avoir de qualificatif de gestion de mémoire ARC car un pointeur qui pointe vers une adresse mémoire est un pointeur vers un type primitif, pas un pointeur vers un objet. Cependant, lorsque vous déclarez un double pointeur, ARC souhaite savoir quelles sont les règles de gestion de la mémoire pour le deuxième pointeur. C'est pourquoi les variables de pointeur double sont spécifiées comme suit:
Ainsi, dans le cas d'un argument de méthode qui est un double pointeur NSError, le type de données est déclaré comme:
qui en anglais dit "pointeur vers un pointeur d'objet NSError __autoreleasing".
la source
La spécification ARC définitive dit que
Par exemple, le code
est réellement converti en
... c'est pourquoi cela fonctionne lorsque vous avez un paramètre
NSError* __autoreleasing * errorPointer
, la méthode appelée affectera alors l'erreur à*errorPointer
et la sémantique ci-dessus entrera en vigueur.Vous pouvez utiliser
__autoreleasing
dans un contexte différent pour forcer un objet ARC dans le pool de libération automatique, mais ce n'est pas très utile car ARC semble uniquement utiliser le pool de libération automatique au retour de méthode et le gère déjà automatiquement.la source