NSError et __ _ _ autoreleasing
Quelqu'un peut-il m'expliquer le but d'avoir __autoreleasing
dans l'exemple de code suivant bloc?
- (void)execute:(NSError * __autoreleasing *)error {
//do stuff, possibly assigning error if something went wrong
}
J'ai enlevé le __autoreleasing
et tout semble encore à compiler/exécuter amende. J'ai commencé à utiliser l'obj-c poste à l'ARC donc je n'ai jamais vraiment appris/compris tous ceux de double underscore thingamajigs. J'ai lu le ARC guide de transition, mais je ne comprends pas tout leur NSError exemple.
Vous devez vous connecter pour publier un commentaire.
Examiner comment l'ARC travaille avec variables - chaque variable de référence dispose d'un mode (implicite ou explicite): forte, faible, etc. Ce mode laissez ARC de savoir comment gérer les lectures et les écritures à cette variable; par exemple pour un forte variable de lecture ne nécessite aucune action supplémentaire lors de l'écriture exige de libérer la référence existante dans la variable avant qu'il ne soit remplacé par le nouveau. ARC besoins de connaître le mode de n'importe quelle variable dans le but de fonctionner.
Maintenant examiner les variables qui sont eux-mêmes passés par référence, par exemple pour vos
execute
vous aurez un appel le long des lignes de:et le corps de
execute
contiendra une cession le long des lignes de:Maintenant pour indirects d'affectation ARC besoins de connaître le mode de la variable en question de sorte qu'il sait lire et écrire. Qu'est ce que le
__autoreleasing
est dans la déclaration, il dit à l'ARC qu'il a été adopté une référence à une variable dont la mode est autoreleasing, et qui raconte l'ARC à lire et à écrire le contenu de la variable. Supprimer la__autoreleasing
et un mode par défaut sera assumé, et dans ce cas, je vous conseille d'être plus explicite est certainement une bonne chose.La autoreleasing mode signifie que la variable contient une référence qui n'est pas la propriété, lit doit conserver si nécessaire et d'écriture peuvent écrire juste. Il est principalement utilisé pour les variables passées par référence.
Vous remarquerez peut-être que dans l'exemple ci-dessus, la variable
myError
a mode forte (implicitement) et pourtant il est passé par référence comme autoreleasing - le compilateur gère cela automatiquement par l'introduction d'un temporaire autoreleasing variable, la copie sans en conservant la référence actuelle dansmyError
en elle, et un passage temporaire par référence à l'argument deexecute:
. Après l'appel renvoie le compilateur ne normal d'affectation temporaire àmyError
, qui se traduit dans n'importe quelle référence de la libération et le retour de l'retenu.Pour plus de détails, voir Apple Transition à l'ARC Notes de Version
Suivi de Commentaires
Q: Est
__autoreleasing
implicitement défini?Un: Bien Apple document n'est pas spécifique, mais la Clang documentation dit que c'est implicite pour indirectes paramètres. Comme ci-dessus, je vous recommande d'être explicite, la clarté est une Bonne Chose™.
Q: le placement de la matière?
A: Oui, et non... C'est une déclaration en C, les trucs de questions ("Qu'est la suivante déclarer..."). Le qualificatif doit être entre les deux astérisques que c'est un pointeur vers une variable (de type) autoreleasing pointeur vers un objet, mais Apple a fait état le compilateur est de "pardon", sans être spécifique de ce qu'il pardonne. Jouer la sécurité, le mettre dans le bon endroit.
Q: si vous n'êtes pas de test pour
error
êtreNULL
avant de faire l'indirects d'affectation?A: bien sûr, vous devriez, quelque part, avant que vous ne l'indirection. Le code affiché est juste un aperçu et le détail a été gommés et couverts par la
...
s’. Cependant, comme il a été soulevé à quelques reprises au fil des ans, peut-être que j'ai ramené de trop, unif
a été ajouté.__autoreleasing
implicitement, si je n'est pas explicitement définie? Aussi, le placement de__autoreleasing
question (à l'avant, à l'intérieur de, ou après les astérisques)?error
estNULL
avant d'assigner à*error
. Sinon, votre méthode pourrait provoquer une panne de votre application depuis[foo execute:NULL]
est parfaitement valable, l'exécution et la façon de dire "je n'aime pas à propos de l'erreur".error
n'est PASnil
OUNULL
avant d'assigner*error
ou vous pouvez jeter unEXC_BAD_ACCESS
signal.