2011-01-22 4 views

Respuesta

22

El método guardar toma un puntero a un puntero. There's a good explanation on Cocoa Tutorial: Using NSError to Great Effect

Pasar punteros a los punteros

Utilización de la clase NSError en el ejemplo anterior es bastante simple. Acabo de pasar y si la llamada falló para sea cual sea el motivo, tengo un objeto NSError para explicar cuál era el problema . ¿Pero cómo funciona el otro lado de que llama?

La primera parte de este es entender el concepto de pasar un puntero a un puntero en lugar de un puntero a un objeto . Normalmente cuando se envía un mensaje , se está pasando un puntero al objeto en el mensaje. Esto se denota con la única asterisco (*) en la firma del método como

- (void) appendString: (NSString *) newString Esto es diferente a continuación, pasar un puntero a un puntero. En primer lugar, ese tipo de argumento se denota con dos asterisco (**) tales como:

- (BOOL) ahorra: (NSError **) error En segundo lugar, la otra diferencia es que esto permite el método de recepción de controlar qué el puntero (al que apunta el puntero) está haciendo referencia a. Esto es posiblemente una de las partes más confusas de de la programación del puntero, pero una vez que lo obtienes, es una herramienta muy poderosa. Para decirlo de otra manera, por pasando un puntero al puntero, el método de recepción puede decidir cuál es el valor de la variable . Como puede ver en mi código anterior, inicié la variable de error en nil. Sin embargo, si falla la llamada a guardar , esa variable ya no será nula pero hará referencia a un objeto NSError actual que pueda interrogar a .

Si desea comprender cómo funciona este , sugeriría double indirection wikipedia article como un gran punto de partida de .

9

Cuando se llama al método, no se está dando un puntero a un NSError, que se está dando un lugar para pasar un puntero a una NSError de nuevo a usted.

A menudo escribo

NSError *error = nil; 

que hace que sea un poco más obvio que no hay nada (interesante) en error Cuando se llama a -save:. Es solo un lugar que ha reservado para la dirección en memoria de un objeto NSError.Si el método encuentra un error, crea un objeto NSError y escribe la dirección del objeto en error para devolvérselo.

+8

Solo tenga en cuenta que detecta si se produjo un error por el valor de retorno de los métodos, no comprobando si el error sigue siendo nulo después. –

+0

@Johan - ¡sí! He cometido exactamente el mismo error cuando recién comenzaba con Obj-C. –

7

Los campos de NSError no se pueden configurar. su interfaz es opaca e inmutable. por lo tanto, si tuviera que asignar/iniciar un error, el cliente no podría completarlo. por lo tanto, el enfoque es devolver un nuevo error (si corresponde), también lo salve de los allocs en todos los casos.

dado que el tipo de devolución ya está especificado por el método, y el error es opcional, tiene sentido utilizar este enfoque para devolver el error en la sintaxis idiomatic c.

iow, el cliente no puede cambiar lo que pasa ni devolver el error utilizando :(NSError *)outError, por lo que se aplica el "parámetro de salida" formulario :(NSError**)outError.

+2

esta es la primera vez que entiendo a medias por qué & es bueno, ¡gracias! – brainray

+0

@brainray De nada – justin

+1

Eso tiene sentido. Gracias. – Rakesh

0

Es el operador de la dirección; produce un puntero apuntando al referente. En este caso, el error es un NSError *, le toma una dirección y puede modificar el error a través de ese puntero para indicar el error que ocurrió.

Cuestiones relacionadas