2012-02-22 10 views
7

Me doy cuenta de que esto es similar a una publicación existente aquí, What's the Point of (NSError**)error?, pero mi pregunta es un poco diferente. Entiendo cómo funciona el puntero doble, y cómo este es el patrón de error API común de iOS. Mi pregunta es más sencillo alrededor del puntero, y por qué este código no funciona:NSError * vs NSError **

- (BOOL)someMethodWithError:(NSError *)error 
{ 
    ... 
    if(errorOccured) 
    { 
    NSError *e = [[[NSError alloc] initWithDomain:@"" code:1 userInfo:nil] autorelease]; 
    error = e; 
    return NO; 
    } 

    return YES; 
} 

implementarse usando:

NSError *error = nil; 
if(![someObj someMethodWithError:error]) 
{ 
    NSLog(@"Error: %@", [error localizedDescription]); 
} 

¿Por qué la asignación en la implementación del método reasignar el puntero a la nuevo objeto NSError?

Respuesta

8

Creo que ayuda pensar en un puntero como un número entero. (Eso es lo que es).

Mire su ejemplo con un int.

-(BOOL)someMethodWithError:(int)error 
{ 
    error =100; 
    return NO; 
} 

Ese número entero es pasar por valor. después de esa función se llama error no cambiará.

error = 123; 
    [self someMethodWithError:error]; 
    //error is = 123; 

El puntero es lo mismo. Pasa por valor

NSError * error; //this assigns this to a value in memory. 
    NSLog(@"%p",error); 
    [self someMethodWithError:error]; 
    NSLog(@"%p",error); // the value of error will not have changed. 

Si desea que el puntero cambie, debe enviar un puntero a ese puntero y modificarlo. Es confuso pero dibuja un diagrama de la memoria y piénsalo. :)

+1

Excelente explicación madmik. Gracias. Tiene sentido totalmente ahora que se da cuenta de que el puntero pasa por valor. – Eric

+1

@ madmik3: Puede ser peligroso pensar en un puntero como "solo un número entero".Un puntero es una variable que contiene una dirección. El hecho de que C le permita utilizar operaciones aritméticas como '++' en los punteros no significa que los punteros se comporten como enteros. Por ejemplo, si '++' una variable de tipo 'int', habrá agregado 1 a su valor. Sin embargo, si '++' una variable de tipo 'int *' *, habrá agregado 4 a su valor *. – pje

+0

No sugiero que los considere de la misma manera, pero si observa cómo responden a las variables que pasan, queda claro por qué a veces necesita un doble puntero. Es solo por el ejemplo. :) – madmik3

0

Así es como funciona el lenguaje C. Tal vez le gustaría echar un vistazo a esta pregunta y respuesta: C double pointer, que es básicamente lo mismo con una apariencia diferente.

0

Bueno error que tiene somemethodWithError es puntero diferente que se contiene la dirección del error desde donde se someMethodWithError ser llamado. por lo que cuando se asigna un objeto a error puntero de someMethodWithError no se reflejará en el puntero de error de método desde donde se llama

es como

NSError * error1 = obj1; 
NSError * error2 = error1; 

y después si se asigna ningún nuevo objeto a ERROR2 como

error2 = obj2; 

no va a cambiar el valor del puntero de error1 y todavía apuntará a obj1

3

es una ll sobre el doble puntero.

¿Por qué no se muestra el nuevo valor? Porque nunca modificó el contenido del objeto que inicializó como nulo. Para hacer eso, habría necesitado utilizar una referencia a la ubicación de la memoria donde se almacenó el valor nulo (un puntero al puntero), no solo una copia del valor nulo (que es lo que está pasando usando el puntero único).

Esto es algo muy común en C donde parte de la salida de una función se "devuelve" a través de un puntero en los argumentos de entrada.

Cuestiones relacionadas