2010-01-14 15 views
8

Esempio: Il metodo di NSManagedObjectContext-save: è dichiarato così:Qual è l'errore Point of (NSError **)?

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

Da NSError è già una classe, e passando un puntatore sarebbe effettivamente avere l'effetto di modificare questo oggetto all'interno della attuazione di -save:, qual è il punto di passare un puntatore a un puntatore qui? Qual è il vantaggio/senso? esempio

utilizzati:

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

è necessario inizializzare l'errore su nil nell'esempio – ergosys

+7

No, non è assolutamente necessario inizializzare l'errore su zero. Il valore dell'errore è del tutto indefinito al ritorno del metodo ** a meno che ** il metodo non restituisca nil o NO. – bbum

+0

Avevo sempre inizializzato NSErrors su zero, ma suppongo di aver sbagliato nell'interpretazione di come gli errori sono stati gestiti internamente: http://rentzsch.tumblr.com/post/260201639/nserror-is-hard –

risposta

16

Se hai appena passato un puntatore, tutto il metodo potrebbe modificare l'oggetto NSError già esistente a cui stai puntando.

Passando in un puntatore a un puntatore, è possibile creare nuovi oggetti NSError e lasciarvi con un puntatore che punta a loro.

+5

Sort of. Se hai passato un riferimento a un NSError esistente, l'implementazione NSError dovrebbe supportare la mutabilità. Quello sarebbe un contratto API completamente diverso. Altrimenti, correggere. – bbum

+0

Ho aggiunto un gruppo rilevante di esempi su questa domanda. http://stackoverflow.com/questions/16244597/nserror-returned-with-bad-ad-ress-why – bbum

3

Permette il metodo per allocare un nuovo NSError e modificare il puntatore per puntare a essa, invece di dover modificare la NSError già indicato da (se non è abbastanza grande ?)

+0

Sono confuso. Se stai inviando l'indirizzo a un NSError nullo, non c'è NSError da "modificare" finché non ne crei uno. Inoltre, NSError è immutabile, quindi non puoi modificarlo comunque secondo MacMark sopra. Vorrei poter dare un senso a tutte queste risposte contrastanti. –

3

Il vantaggio è che non è necessario creare l'oggetto NSError. Come la documentazione afferma:

"Un puntatore ad un oggetto NSError Non è necessario creare un oggetto NSError."

+0

Puoi fornire ulteriori chiarimenti su questo, con un esempio forse, perché MacMark sopra dice 'NSError' è immutabile, quindi il tuo solo la scelta è crearne uno. Suppongo che tu intenda che il CALLER non ha bisogno di creare un 'NSError', tuttavia, se viene restituito un errore, sicuramente il CALLED deve creare un' NSError' La tua risposta è un po 'poco chiara. –

6

@Anon è corretta. Aggiungerò: questo è il modo Cocoa per produrre errori, al posto delle eccezioni di lancio.

Nel tuo esempio, si ha:

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

Subito dopo la chiamata a save:, se c'è stato un errore, allora il metodo save: avrà creato un nuovo NSError oggetto, e ha cambiato la variabile error per puntare da nil al nuovo oggetto errore. In questo modo puoi esaminare tu stesso l'oggetto NSError e rispondere in modo appropriato.

IMO, questo è più pulito che lanciare un'eccezione (che nella mia filosofia dovrebbe essere fatta solo quando accade qualcosa di catastrofico e irrecuperabile).

12

È quello che alcune persone chiamano un parametro "fuori".

Non stai passando un puntatore a un oggetto NSError, stai passando un puntatore a una variabile locale . Questo dà al metodo chiamato la possibilità di modificare la variabile locale; in questo caso, per assegnarlo a un'istanza NSError.

Forse la confusione è che la variabile locale che stai passando a save: è essa stessa un puntatore, quindi il tipo di variabile finisce per essere un puntatore a un puntatore.

Bottom line, è un puntatore a una variabile locale e funziona allo stesso modo se la variabile locale è int o NSError*.

+0

ha molto senso ora. grazie a tutti! grandi cose ... – openfrog

+0

Mi piace la tua spiegazione, ma non sono istruito su come una variabile locale nil abbia un indirizzo valido che puoi passare ad un altro metodo. Puoi per favore approfondire su quel pezzo –

1

Se hai appena passato in un puntatore, tutto il metodo potrebbe fare sarebbe alterare il oggetto NSError già esistente che si punta a.

Non è possibile modificare un oggetto NSError.

NSError è immutabile. Questo è il motivo per cui hai bisogno del puntatore alla variabile NSError. Puoi creare solo un NSError nuovo di zecca. In questo modo cambi il puntatore in modo che punti al tuo NSError appena creato.

Problemi correlati