Pourquoi ne NSError besoin de double indirection? (pointeur vers un pointeur)
Ce concept semble me fasse de la peine. Pourquoi un NSError objet de son pointeur passé à une méthode qui est la modification de l'objet? Par exemple, ne serait pas juste de passer une référence à l'erreur de faire la même chose?
NSError *anError;
[myObjc doStuff:withAnotherObj error:error];
puis dans doStuff:
- (void)doStuff:(id)withAnotherObjc error:(NSError *)error
{
//something went bad!
[error doSomethingToTheObject];
}
Pourquoi ne pas le travail ci-dessus comme la plupart des autres objets de messagerie habitudes de travail? Pourquoi doit, au contraire, nous avons une erreur d'utilisation:(NSError **)erreur?
Vous devez vous connecter pour publier un commentaire.
La
NSError**
modèle est utilisé lorsque la méthode renvoie normalement une certaine valeur, mais plutôt peut-être besoin de retourner un objet d'erreur (de typeNSError*
) en cas d'échec. En Objective-C, une méthode ne peut retourner un type d'objet, mais c'est un cas où vous voulez retourner deux. C-comme langues lorsque vous avez besoin de retourner une valeur supplémentaire que vous demandez pour un pointeur vers une valeur de ce type, de sorte que le retour d'unNSError*
vous avez besoin d'unNSError**
paramètre. De façon plus réaliste exemple serait celui-ci:Si vous n'aviez qu'un
NSError*
paramètre au lieu d'unNSError**
puisdoStuff
ne serait jamais en mesure de passer à l'erreur de l'objet appelant.Tout simplement:
si vous passez un pointeur vers un objet de votre fonction, la fonction ne peut modifier que le pointeur pointe.
si vous passez un pointeur vers un pointeur vers un objet, puis la fonction peut modifier le pointeur vers un autre objet.
Dans le cas de NSError, la fonction souhaiterez peut-être créer un nouveau NSError objet et de vous passer de retour d'un pointeur vers cette NSError objet. Ainsi, vous avez besoin de double indirection de sorte que le pointeur peut être modifié.
NSError*
...doStuff
ne serait jamais en mesure de passer à l'erreur de l'objet de l'appelant". Votre réponse "la fonction peut modifier le pointeur vers un autre objet" explique clairement POURQUOI vous voulez la**
si l'appelant peut déjà voir des changements avec un pointeur.Une vieille question, mais je pense que sa vaut le coup d'investir ici -
Le véritable coupable est NSError. Si vous regardez à sa classe de référence, il n'existe pas de setter pour un de ses attributs, c'est à dire de domaine, un code ou userInfo. Donc, il n'y a aucun moyen, il vous suffit d'allocation et initialisation d'un NSError, le passer à la méthode, puis de renseigner les informations sur le passé NSError objet. (S'il y avait eu une méthode de définition, nous pourrions avoir passé juste une NSError * et fait quelque chose comme erreur.code = 1 dans la méthode.)
Donc, dans le cas où il y a une erreur, vous devez générer un nouveau NSError objet dans la méthode, et si vous faites ainsi, la seule façon de le transmettre à l'appelant, c'est d'avoir un NSError ** argument. (Pour la raison expliquée dans les réponses ci-dessus.)
Rapport alternatif de ce n8gray dit:
Parce que vous n'êtes pas de la réception d'un objet à envoyer des messages; vous êtes la création de l'objet et de le retourner. Vous devez généralement le pointeur-vers-un-
NSError *
variable d'argument parce que vous ne pouvez utiliser lereturn
déclaration sur une chose à la fois, et vous l'utilisez déjà avecNO
.C
sur**
j'ai atterri ici sur ce post. Excusez-moi, je n'ai pas encore tout à fait le faire: si nous avons passé une seule*
(un pointeur vers un objet), cela devrait suffire pour apporter des modifications à l'objet, à droite? Pourquoi avons-nous encore besoin de passer un pointeur vers un pointeur vers un objet afin d'apporter des modifications à un objet? Merci beaucoup à l'avance. Ce qui concerne.*
(un pointeur vers un objet), cela devrait suffire pour apporter des modifications à l'objet, non?” La droite. Vous avez seulement besoin du pointeur vers l'objet à envoyer des messages à cet objet. “Pourquoi avons-nous encore besoin de passer un pointeur vers un pointeur vers un objet afin d'apporter des modifications à un objet?” Parce que vous n'êtes pas apporter des modifications à un objet; vous êtes en train de créer un nouvel objet et de le retourner à l'appelant. Vous le faire en l'assignant à l'adresse de l'appelant vous a donné—le pointeur vers la variable à laquelle vous placez le pointeur de l'objet.&error
), comment est-ce de travailler avec mes nouveauxNSError
instance créée à l'intérieur de la fonction (*error = [NSError errorWithDomain:...]
)?Je n'ai toujours pas obtenir l'image complète en lisant toutes les réponses ci-dessus. Le profane exercice je l'ai fait ci-dessous, enfin m'a aidé à comprendre ce qui se passe. Il suffit de le mettre là au cas où il aide les débutants à d'autres.
Supposons que vous avez
Dans une autre partie du code, vous avez la séquence suivante
Lorsque vous appelez
[objectX methodX:array]
, ce qui est reçu par la méthode est un copie dearray
. Depuis le tableau contient une adresse (j'.e est un pointeur), le copie est de spécial que ce qui est reçu est une autre variable avec l'adresse ZZZ en elle.Donc, si methodX ne
[array removeObjectAtIndex:0]
, puis l'objet commençant à l'adresse ZZZ est affecté (maintenant ne contient qu'un seul NSNUmber @(2)). Ainsi, lorsque le retour de la méthode, le tableau d'origine également en soit affectée.Suppose au contraire methodX ne
array = [@[@(2)] mutableCopy];
puis tableau d'origine ne soit pas affectée. C'est parce que vous ne vont pas dans l'adresse ZZZ et changer quelque chose. Au lieu de cela vous a remplacé le ZZZ dans la copie reçu par la méthode à une adresse différente de YYY. YYY adresse est le début d'un NSMUtableArray objet avec un élément NSNUmber @(2). L'original ZZZ adresse contient toujours un NSMUtableArray avec deux éléments. @(1) et @(2). Donc, si la méthode retourne, le tableau d'origine est intact.