34 votes

Pourquoi `&` (esperluette) est-il placé devant certains paramètres de méthode?

Je me suis demandé, pourquoi est-ce que devant une NSError, comme ci-dessous, mettons-nous: &error et non error ?

Par exemple

 NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
 

J'espère que vous pourrez expliquer, est-ce toujours le cas ou seulement dans certaines situations, cela est nécessaire? Merci.

59voto

dasblinkenlight Points 264350

Vous avez besoin de prendre l'adresse de l' error parce que la fonction a besoin de la modifier. error est passé par pointeur, si vous avez besoin de "prendre" adresse de l'opérateur & pour elle.

C et Objective-C de passer des paramètres par valeur. Si vous passez error sans une esperluette et la méthode que vous appelez les modifie, votre fonction qui fait l'appel ne serait pas voir tous les changements, parce que la méthode fonctionnerait sur sa copie locale de l' NSError*.

Vous savez que vous avez besoin d'une esperluette en face du paramètre correspondant si vous regardez la signature de la méthode et de voir ** il y:

- (NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error
                                            //   ^ one                    ^^ two

8voto

UIAdam Points 3945

L' error paramètre est de type (NSError **), qui est un pointeur vers un pointeur vers un NSError. L' error variable que vous utilisez comme argument est probablement déclarée NSError *, de sorte que pour obtenir le type de match correctement, vous devez utiliser l'adresse de l'opérateur pour obtenir un pointeur vers un pointeur (&error). La raison, la méthode a besoin d'un pointeur vers un pointeur, en premier lieu, afin qu'il puisse modifier la valeur de error et pour que la nouvelle valeur soit disponible pour vous, l'appelant de la méthode.

6voto

Kristian Glass Points 12506

Essentiellement, la racine du problème est un hack pour vouloir y retourner une deuxième (facultatif) de l'objet.

Comment pouvons-nous faire, que nous ne pouvons que renvoyer une chose? Eh bien, nous pourrions revenir à une certaine sorte d' (return_value, error) tuple, mais c'est un peu lourd. Nous pouvons avoir autant de paramètres que nous aimons bien, nous pouvons faire quelque chose avec ces...

Ainsi, les méthodes/fonctions ne peuvent pas modifier leurs paramètres (pour être précis, ils fonctionnent avec une copie, donc toutes les modifications qu'ils font sont locales). C'est-à-dire (problèmes de concurrence à part) la valeur de fetchRequest avant le message dans votre question sera égal à la valeur de fetchRequest par la suite. Remarque l'objet pointé par fetchRequest peut changer, mais la valeur de fetchRequest lui-même ne sera pas.

Cela nous met un peu dans une impasse. Sauf, attendre, nous savons que nous pouvons heureux de prendre la valeur d'un paramètre et modifier ce qu'il désigne! Si vous regardez la déclaration de executeFetchRequest:error: vous verrez qu'il prend un NSError**. C'est "un pointeur vers un pointeur vers un NSError". Donc, on peut initialiser un vide/balançant NSError*, trouver l'adresse de celui-ci (avec le unaire & opérateur), et le passer en. La méthode peut alors attribuer à l' NSError* pointé par ce.

Voila, nous avons effectivement l'option supplémentaire de valeurs de retour.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: