2009-08-28 11 views

Respuesta

13

no hay paso por referencia (en C++ sentido) en C. Objetivo Puede pasar sus objetos por el puntero, y para los tipos primitivos por valor.

Ejemplo:

void func(NSString* string) 
{ 
    ... 
} 

void func(NSInteger myint) 
{ 
... 
} 

.. 
NSString* str = @"whatever"; 
NSInteger num = 5; 

func(str); 
func(num); 
+1

Estoy totalmente de acuerdo! Siempre en sentido C++: Pasar por referencia significa que si cambia el parámetro de un método (función) para apuntar a otro obj, el mundo exterior se verá afectado (param es simplemente otro nombre de la var pasada), y esto no se puede hacer en Objective C sin desreferenciar el parámetro, porque siempre se pasa una ** copia ** del puntero a métodos (funciones). – Vassilis

+1

En Objective C, el puntero de desreferencia de un objeto es extremadamente raro. Si quiere cambiar el valor de un parámetro de método, normalmente usa cualquiera de las dos formas siguientes. Frist, use el puntero a punteros (direccionamiento indirecto doble, denotado por **), como en muchos ejemplos de NSError. Segundo, envuelve el método como un bloque. A continuación, coloque la variable en el mismo alcance léxico que el bloque y denote el tipo de almacenamiento '__block'. – Philip007

0

Depende de lo que quiere decir. Lo más parecido que C (y, por lo tanto, Objective-C) tiene a un tipo de referencia son punteros. Como su nombre lo indica, los punteros apuntan a datos que existen en otro lugar. Para que se apunte a la cosa, debe desreferenciar el puntero. Los objetos en Objective-C nunca se acceden directamente: siempre usa punteros para hablar con ellos. También puede pasar punteros a otros tipos que no sean objetos.

Los punteros son un tema un tanto complicado. Definitivamente recomendaría leer sobre C para tener una idea de ellos.

88

Pass por referencia en Objective-C es el mismo ya que está en C.

El equivalente al siguiente código C#:

void nullThisObject(ref MyClass foo) 
{ 
    foo = null; 
} 

MyClass bar = new MyClass(); 
this.nullThisObject(ref bar); 
assert(bar == null); 

es

- (void)nilThisObject:(MyClass**)foo 
{ 
    [*foo release]; 
    *foo = nil; 
} 

MyClass* bar = [[MyClass alloc] init]; 
[self nilThisObject:&bar]; 
NSAssert(bar == nil); 

y

- (void)zeroThisNumber:(int*)num 
{ 
    *num = 0; 
} 

int myNum; 
[self zeroThisNumber:&myNum]; 
NSAssert(myNum == 0); 
+7

¡Por favor corrígeme si estoy equivocado!Pero creo que en el ejemplo 'zeroThisNumber' anterior, el puntero se pasa por ** valor **, lo que significa que se pasa una copia del puntero, es decir, si cambiamos el' num' para apuntar a otro int el 'myNum' no cambiará. Nosotros por convención decimos "por referencia" como teniendo la dirección del obj original, podemos cambiarlo directamente (desreferenciando). – Vassilis

+0

Realmente no sé cómo pasar un valor por referencia real en el objetivo C como en C++. Siempre utilizo '' 'y' ** 'como describe Darren, pero igual se pasa una copia del puntero como mencioné en mi comentario anterior (sin embargo, el trabajo ya está hecho). Por supuesto, este es un tipo de problema teórico. – Vassilis

+2

En el ejemplo zeroThisNumber, num se pasa por referencia (aunque técnicamente este no es el significado de referencia de C++). En este ejemplo, la dirección del valor de num se pasa a zeroThisNumber. Esto permite que el valor se modifique dentro del método y que ese cambio se refleje en la persona que llama. A lo que te refieres sería a una referencia a una referencia ... como si fuera ... doble indirección. Si num no se pasa por referencia, el valor de num se copiará y se colocará en la pila. Cualquier cambio en num dentro de zeroThisNumber se haría en la pila y se perdería cuando el método retorne. – Jason

13

Si utiliza Objecti ve C++, lo que puede hacer al nombrar a su archivo con extensión .mm, o decirle a Xcode para recopilar todas las fuentes como Objective C++, entonces puede pasar de referencias en la misma forma que se hace con C++, por ejemplo:

- (OSStatus) fileFileInfo: (FileInfo&)fi; 
0

Hay un argumento que se debe tener si desea obtener más de una dirección de una llamada de función resultante. Puede hacerlo en su lugar creando una clase contenedora y pasándola en su lugar. Por ejemplo:

@interface AddressWrapper : NSObject { 
    NSArray  *array; 
    NSString *string; 
} 

@property (nonatomic, assign) NSArray *array; 
@property (nonatomic, assign) NSString *string; 
@end 

En * .m:

@implementation AddressWrapper 
@synthesize array, string; 
@end 



-(void) getAddresses: (AddressWrapper*) wrapper { 
    wrapper.array = myNSArray; 
    wrapper.string = myNSString; 
} 
7

Trate de esta manera:

-(void)secondFunc:(NSInteger*)i 
    { 
     *j=20; 
    //From here u can change i value as well 
    //now i and j value is same (i.e i=j=20) 
    } 
    -(void) firstFunc 
    { 
     NSInteger i=5; 
     [self secondFunc :&i]; 
    //i value is 20 
    } 

espero que ayude !!

Cuestiones relacionadas