Qu’est-ce que la double écanvas (par exemple, NSError **)?

Donc, j’ai vu ceci:

error:(NSError **)error 

dans le doc Apple. Pourquoi deux écanvass? Quelle est la signification?

Une “double écanvas” est un pointeur sur un pointeur. Ainsi, NSError ** est un pointeur sur un pointeur vers un object de type NSError . Il vous permet essentiellement de retourner un object d’erreur de la fonction. Vous pouvez créer un pointeur sur un object NSError dans votre fonction (appelez-le *myError ), puis faites quelque chose comme ceci:

 *error = myError; 

pour “renvoyer” cette erreur à l’appelant.


En réponse à un commentaire posté ci-dessous:

Vous ne pouvez pas simplement utiliser un NSError * car en C, les parameters de fonction sont passés par valeur, c’est-à-dire que les valeurs sont copiées lorsqu’elles sont transmises à une fonction. Pour illustrer cela, considérons cet extrait de code C:

 void f(int x) { x = 4; } void g(void) { int y = 10; f(y); printf("%d\n", y); // Will output "10" } 

La réaffectation de x dans f() n’affecte pas la valeur de l’argument en dehors de f() (dans g() , par exemple).

De même, lorsqu’un pointeur est passé dans une fonction, sa valeur est copiée et la réaffectation n’affectera pas la valeur en dehors de la fonction.

 void f(int *x) { x = 10; } void g(void) { int y = 10; int *z = &y; printf("%p\n", z); // Will print the value of z, which is the address of y f(z); printf("%p\n", z); // The value of z has not changed! } 

Bien sûr, nous soaps que nous pouvons changer assez facilement la valeur de z :

 void f(int *x) { *x = 20; } void g(void) { int y = 10; int *z = &y; printf("%d\n", y); // Will print "10" f(z); printf("%d\n", y); // Will print "20" } 

Donc, il va de NSError * que pour changer la valeur de ce qu’un NSError * pointe, il faut aussi passer un pointeur sur le pointeur.

En C tout est passe par valeur. Si vous voulez changer la valeur de quelque chose, vous lui passez l’adresse (qui passe la valeur de l’adresse mémoire). Si vous souhaitez modifier l’endroit où un pointeur pointe, vous passez les adresses du pointeur.

Jetez un oeil ici pour une explication simple .

En C, une écanvas double est un pointeur sur un pointeur. Il y a plusieurs raisons à cela. La première est que le pointeur peut être un tableau de pointeurs. Une autre raison serait de passer un pointeur sur une fonction, où la fonction modifie le pointeur (similaire à un paramètre “out” dans les autres langages).

La notation double écanvas (**) n’est pas spécifique à l’initialisation d’une variable dans une classe. C’est simplement une double référence indirecte à un object.

  float myFloat; // an object float *myFloatPtr; // a pointer to an object float **myFloatPtrPtr; // a pointer to a pointer to an object myFloat = 123.456; // initialize an object myFloatPtr = &myFloat; // initialize a pointer to an object myFloatPtrPtr = myFloatPtr; // initialize a pointer to a pointer to an object myFloat; // refer to an object *myFloatPtr; // refer to an object through a pointer **myFloatPtrPtr; // refer to an object through a pointer to a pointer *myFloatPtrPtr; // refer to the value of the pointer to the object 

La notation à double pointeur est utilisée lorsque l’appelant a l’intention de modifier l’un de ses propres pointeurs par un appel de fonction. L’adresse du pointeur, au lieu de l’adresse de l’object, est transmise à la fonction.

Un exemple pourrait être l’utilisation d’une liste chaînée. L’appelant maintient un pointeur sur le premier nœud. L’appelant appelle des fonctions pour rechercher, append et supprimer. Si ces opérations impliquent l’ajout ou la suppression du premier nœud, le pointeur de l’appelant doit changer, pas le pointeur .next dans aucun des nœuds, et vous avez besoin de l’adresse du pointeur pour cela.

Si c’est quelque chose comme C, alors ** signifie un pointeur sur un pointeur.