iphone - ver - ¿Por qué `&`(ampersand) se pone delante de algunos parámetros del método?
itunes (3)
Básicamente, la raíz del problema es un truco para querer devolver un segundo objeto (opcional).
¿Cómo podemos hacer esto, ya que solo podemos devolver una cosa? Bueno, podríamos devolver algún tipo de tupla (return_value, error)
, pero eso es un poco difícil de manejar. Sin embargo, podemos tener todos los parámetros que queramos, ¿podemos hacer algo con eso?
Por lo tanto, los métodos / funciones no pueden modificar sus parámetros (para ser precisos, operan con una copia, por lo que cualquier modificación que realicen es local). Es decir (a un lado las cuestiones de concurrencia) el valor de fetchRequest
antes de que el mensaje en su pregunta sea igual al valor de fetchRequest
después. Tenga en cuenta que el objeto al que apunta fetchRequest
podría cambiar, pero el valor de fetchRequest
no lo hará.
Esto nos pone en un aprieto. Excepto, espera, sabemos que podemos tomar el valor de un parámetro y modificar lo que señala. Si miras la declaración de executeFetchRequest:error:
verás que toma un NSError**
. Eso es "un puntero a un puntero a un NSError
". Entonces, podemos inicializar un NSError*
vacío / colgante, encontrar la dirección del mismo (con el operador unario ), y pasarlo. El método puede asignar al NSError*
señalado por esto.
Voila, efectivamente tenemos valores de retorno adicionales opcionales.
Me pregunto, ¿por qué es que delante de un NSError, como a continuación, ponemos: &error
y no error
?
P.ej
NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
Espero que puedas explicar, ¿siempre es así o solo en ciertas situaciones esto es necesario? Gracias.
Debe tomar la dirección de error
porque la función necesita modificarla. error
se pasa por el puntero , por lo que necesita el operador "tomar la dirección" &
para ello.
C y Objective-C pasan parámetros por valor . Si pasa el error
sin un ampersand y el método que llama lo modifica, su función que hizo la llamada no vería ningún cambio, porque el método funcionaría en su copia local de NSError*
.
Sabes que necesitas un símbolo comercial delante del parámetro correspondiente si miras la firma del método y ves **
allí:
- (NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error
// ^ one ^^ two
El tipo del parámetro de error
es (NSError **)
, que es un puntero a un puntero a un NSError. La variable de error
que utiliza como argumento probablemente se declare como NSError *
, por lo que para que los tipos coincidan correctamente, debe usar la dirección del operador para obtener un puntero a un puntero ( &error
). La razón por la que el método necesita un puntero a un puntero en primer lugar es para poder modificar el valor del error
y tener ese nuevo valor disponible para usted, el que llama del método.