2010-01-14 10 views
8

Exemple: La méthode -save: de NSManagedObjectContext est déclarée comme ceci:Quel est le point d'erreur (NSError **)?

- (BOOL)save:(NSError **)error 

Depuis NSError est déjà une classe, et le passage d'un pointeur aurait effectivement pour effet de modifier cet objet dans la mise en œuvre de -save:, quel est le point de passer un pointeur sur un pointeur ici? Quel est l'avantage/le sens?

Exemple d'utilisation:

NSError *error; 
if (![managedObjectContext save:&error]) { 
    // Handle the error. 
} 
+3

vous devez initialiser l'erreur à zéro dans cet exemple – ergosys

+7

Non, il n'y a absolument pas besoin d'initialiser l'erreur à zéro. La valeur de l'erreur est entièrement indéfinie lors du retour de la méthode ** sauf si ** la méthode a renvoyé nil ou NO. – bbum

+0

J'avais toujours initialisé NSErrors à zéro, mais je crois que je me suis trompé dans mon interprétation de la façon dont les erreurs ont été traitées en interne: http://rentzsch.tumblr.com/post/260201639/nserror-is-hard –

Répondre

16

Si vous venez de passer un pointeur, toute la méthode pourrait modifier l'objet NSError que vous pointez. En passant dans un pointeur vers un pointeur, il peut créer de nouveaux objets NSError et vous laisser avec un pointeur qui pointe vers eux.

+5

Trier par. Si vous avez passé une référence à une erreur NSError existante, l'implémentation de NSError doit prendre en charge la mutabilité. Ce serait un contrat API entièrement différent. Sinon, corrigez. – bbum

+0

J'ai ajouté un ensemble pertinent d'exemples sur cette question. http://stackoverflow.com/questions/16244597/nserror-returned-with-bad-address-why – bbum

3

Il permet à la méthode d'allouer une nouvelle NSError et changer le pointeur pour pointer vers elle, plutôt que de devoir modifier le NSError déjà signalé à (si ce n'est pas assez grand ?)

+0

Je suis confus. Si vous envoyez l'adresse à un NSError nul, il n'y a pas d'erreur NSError à 'modifier' jusqu'à ce que vous en créiez un. De plus, NSError est immuable, donc vous ne pouvez pas le modifier de toute façon selon MacMark ci-dessus. Je voudrais pouvoir donner un sens à toutes ces réponses contradictoires. –

3

L'avantage est que vous n'avez pas besoin de créer l'objet NSError. Comme la documentation indique:

«Un pointeur vers un objet NSError Vous n'avez pas besoin de créer un objet NSError. »

+0

Pouvez-vous fournir plus de précisions à ce sujet, un exemple peut-être, parce que MACmark ci-dessus dit 'NSError' est immuable, de sorte que votre seule le choix est d'en créer un. Je suppose que vous voulez dire que le CALLER n'a pas besoin de créer un 'NSError', cependant, si une erreur va être retournée, alors le CALLED a besoin de créer un' NSError' Votre réponse est un peu floue. –

6

@Anon est correcte. Je vais ajouter: C'est la façon Cocoa de produire des erreurs, au lieu de lancer des exceptions.

Dans votre exemple, vous avez:

NSError *error = nil; 
if (![managedObjectContext save:&error]) { 
    // Handle the error. 
} 

Immédiatement après l'appel à save:, s'il y avait une erreur, la méthode save: aura créé un nouvel objet NSError et changé pour pointer votre variable error de nil au nouvel objet d'erreur. De cette façon, vous pouvez examiner vous-même l'objet NSError et y répondre de manière appropriée. IMO, c'est plus propre que de lancer une exception (ce qui dans ma philosophie devrait seulement être fait quand quelque chose de catastrophique et irrécupérable se produit).

12

C'est ce que certains appellent un paramètre "out". Vous ne passez pas un pointeur vers un objet NSError, vous passez un pointeur vers une variable locale . Cela donne à la méthode appelée la possibilité de modifier votre variable locale; dans ce cas, pour l'affecter à une instance NSError.

Peut-être que ce qui prête à confusion est que la variable locale que vous passez à save: est elle-même un pointeur, donc le type de variable finit par être un pointeur vers un pointeur.

Ligne inférieure, c'est un pointeur vers une variable locale, et cela fonctionne de la même manière que la variable locale soit int ou NSError*.

+0

a beaucoup de sens maintenant. Merci tout le monde! super choses ... – openfrog

+0

J'aime votre explication, mais je ne suis pas instruit dans la façon dont une variable locale nulle a une adresse valide, vous pouvez passer à une autre méthode. Pouvez-vous s'il vous plaît élaborer sur cette pièce –

1

Si vous venez de passer à un pointeur, tous la méthode pourrait faire altérerait l'objet NSError déjà existant que vous êtes pointe.

Vous ne pouvez pas modifier un objet NSError.

NSError est immuable. C'est la raison pour laquelle vous avez besoin du pointeur vers la variable NSError. Vous pouvez uniquement créer une nouvelle marque NSError. Ainsi, vous changez le pointeur pour pointer vers votre NSError nouvellement créé.

Questions connexes