web-dev-qa-db-fra.com

Objectif C - Passer par valeur et passer par référence

Tout d'abord, désolé pour cette question simple. Mais j'ai besoin de comprendre ce qui se passe.

Je pensais que la sortie devrait êtreupper case string. Mais il s’agit deUPPER CASE STRING.

- (void)test
{
     NSString *stringVar = @"UPPER CASE STRING";
     [self changeString:stringVar];
     NSLog(@"value after changed : %@", stringVar);
}

- (void)changeString:(NSString*)string
{
     string = [string lowercaseString];
}

Que se passe-t-il et comment y remédier?

24
Charith Nidarsha

L'appel [string lowercaseString] crée un objet new NSString que vous affectez à la variable locale string. Cela ne change pas la valeur de stringVar en dehors de la fonction changeString. Le pointeur lui-même est passé par valeur.

Une façon de faire ce que vous voulez est de passer un pointeur à un autre:

-(void) test
{
     NSString *stringVar = @"UPPER CASE STRING";
     [self changeString:&stringVar];
     NSLog(@"value after changed : %@", stringVar);
}

-(void) changeString:(NSString**)string
{
     *string = [*string lowercaseString];
}
58
Greg Hewgill

Si vous regardez la référence à la méthode [NSString lowerCaseString] _ , vous pouvez voir qu'elle renvoie une nouvelle chaîne, avec les caractères en minuscule:

Renvoie la représentation en minuscule du destinataire.

- (NSString *)lowercaseString

Votre code ne fait que remplacer la référence à la chaîne d'entrée par la sortie de l'appel lowercaseString, qui n'a aucun effet. Le meilleur moyen de résoudre ce problème consiste à vous renvoyer la valeur vous-même, ce qui facilite la compréhension de la méthode:

-(void) test
{
     NSString *stringVar = @"UPPER CASE STRING";
     stringVar = [self changeString:stringVar];
     NSLog(@"value after changed : %@", stringVar);
}

-(NSString *) changeString:(NSString*)string
{
     string = [string lowercaseString];
     return string;
}

Vous devez comprendre que NSString est immuable, il est donc impossible, sauf de réaffecter la référence, de modifier le contenu d'une chaîne. Vous pouvez cependant utiliser NSMutableString à la place, ce qui peut être modifié sur place.

7
trojanfoe

Je fais référence au problème ci-dessus et je vous aide à corriger l'erreur.Trouvez mes commentaires

- (void)test
{
     NSString *stringVar = @"UPPER CASE STRING";
     //StringVar is a pointer to integer class.let us assume the address the stringVar be 0x50 and the value it has be 0x100
     //So 0x100 has the string 

     [self changeString:stringVar];
     //above we are calling the method to lowercase and argument is stringVar
     //As the method is called we pass 0x100 in the argument as this is the memory where the value is kept

     NSLog(@"value after changed : %@", stringVar);
    //Our StringVar still points to 0x100 where the value is in upperString
}

- (void)changeString:(NSString*)string
{
     string = [string lowercaseString];
    // Now operation performed on string returns a new value on suppose location 0x200
   //String parameter passed in argument is assigned the new value.But we never pass values as we pass only location under the hood
   //New parameter passed now points to new memory location 0x200

}

---------------------------------------------------------------------------------
With the new solution
-(void) test
{
     NSString *stringVar = @"UPPER CASE STRING";
     //let 0x50 be stringVar memorylocation pointing to 0x100 with above value
     [self changeString:&stringVar];
     //0x50 is passed in argument
     NSLog(@"value after changed : %@", stringVar);
     //On new location stored in address of stringVar it points to new string value
}

-(void) changeString:(NSString**)string
{
     *string = [*string lowercaseString];
     //0x200 is new memory location received.*string gives the 0x100 location and hence the value
   //LHS is assigned to new location .On LHS you find *string which will be assigned 0x200
   //As string with location 0x50 is value 0x200 which will make it to point new      location where lowercase string exist
}
1
Suryanarayan Sahu

la chaîne dans -(void) changeString:(NSString*)string est une variable locale, modifiez la méthode pour renvoyer une valeur:

-(void) test
{
     NSString *stringVar = @"UPPER CASE STRING";
     stringVar =[self changeString:stringVar];
     NSLog(@"value after changed : %@", stringVar);
}
-(NSString *) changeString:(NSString*)string
{
    return [string lowercaseString];
}
0
mas'an

string est une variable locale (un pointeur sur une chaîne NSString immuable), vous changez simplement les points string dans la fonction locale, mais lorsque vous renvoyez sa valeur, elle sera supprimée.

Vous voudrez peut-être simplement passer la chaîne en tant que paramètre et renvoyer la chaîne en minuscule à partir de la fonction.

0
Joachim Isaksson