2009-08-28 9 views

Répondre

13

Il n'y a pas en passant par référence (en C++ sens) dans l'objectif C. Vous pouvez passer vos objets par pointeur, et pour les types primitifs en valeur.

Exemple:

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

void func(NSInteger myint) 
{ 
... 
} 

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

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

Je suis totalement d'accord! Toujours dans le sens C++: Passer par référence signifie que si vous changez le paramètre d'une méthode (fonction) pour pointer vers un autre obj, le monde extérieur sera affecté (param est juste un autre nom de la var passée), et ceci ne peut pas être fait en Objective C sans déréférencer le paramètre, car toujours une ** copie ** du pointeur est passée aux méthodes (fonctions). – Vassilis

+1

En Objective C, le pointeur de déréférencement d'un objet est extrêmement rare. Si vous souhaitez modifier la valeur d'un paramètre de méthode, vous utilisez généralement l'une des deux méthodes suivantes. Frist, utilisez le pointeur vers des pointeurs (double indirection, indiqué par **), comme dans beaucoup d'exemples NSError. Deuxièmement, wrap méthode comme un bloc. Placez ensuite la variable dans la même portée lexicale que le bloc et notez-la par le type de stockage '__block'. – Philip007

0

Cela dépend de ce que vous voulez dire. La chose la plus proche C (et donc Objective-C) a un type de référence est pointeurs. Comme son nom l'indique, les pointeurs pointent vers des données qui existent ailleurs. Afin d'obtenir la chose pointée, vous devez déréférencer le pointeur. Les objets dans Objective-C ne sont jamais directement accessibles - vous utilisez toujours des pointeurs pour leur parler. Vous pouvez également passer des pointeurs vers d'autres types que des objets.

Les pointeurs sont un sujet délicat. Je recommande vivement de lire sur C pour avoir une idée d'eux.

88

passage par référence en Objective-C est le même que dans C.

L'équivalent au code C#:

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

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

est

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

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

et

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

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

S'il vous plaît corrigez-moi si je me trompe!Mais je pense que dans l'exemple 'zeroThisNumber' ci-dessus, le pointeur est passé par ** value **, signifiant qu'une copie du pointeur est passée, c'est-à-dire si nous changeons le' num' pour pointer vers un autre int le 'myNum' ne changera pas. Nous par convention disons "par référence" comme ayant l'adresse de l'obj original, nous pouvons directement le changer (en le déréférenciant). – Vassilis

+0

Je ne sais vraiment pas comment passer une valeur par référence réelle dans l'objectif C comme dans C++. J'utilise toujours le '*' et le '**' comme décrit par Darren, mais toujours une copie du pointeur est passée comme je l'ai mentionné dans mon commentaire précédent (le travail est fait cependant). Bien sûr, c'est une sorte de problème théorique. – Vassilis

+2

Dans l'exemple zeroThisNumber, num est passé par référence (bien que techniquement ce n'est pas le sens de référence C++). Dans cet exemple, l'adresse de la valeur de num est passée à zeroThisNumber. Cela permet à la valeur d'être modifiée dans la méthode et d'avoir ce changement reflété dans l'appelant. Ce à quoi vous faites allusion serait une référence à une référence ... pour ainsi dire ... une double indirection. Si num n'était pas passé par référence, la valeur de num serait copiée et placée sur la pile. Toute modification de num dans zeroThisNumber sera effectuée sur la pile et perdue lors du retour de la méthode. – Jason

13

Si vous utilisez Objecti ve C++, que vous pouvez faire en nommant votre fichier avec l'extension .mm, ou dire Xcode pour compiler toutes les sources comme Objective C++, vous pouvez passer des références de la même manière que vous faites avec C++, par exemple:

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

Il y a un argument à avoir si vous voulez obtenir plus d'une adresse d'un appel de fonction résultant. Vous pouvez le faire à la place en créant une classe wrapper et en la passant à la place. Par exemple:

@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

Essayez de cette façon:

-(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 
    } 

Hope it helps !!

Questions connexes