2009-09-09 8 views
2

J'ai trois bouton nommé (intitulé) bonjour, rien, ciel et une étiquette (IBOutlet UIlabel lab). Je veux afficher trois messages diff pour trois clic sur le bouton diff. Mais le code suivant n'a pas réussi à accomplir cela. Quelqu'un peut-il suggérer une idée?objectif c Comparaison NSString

-(IBAction)buttonclick:(id)sender 
{ 

    NSString *title=[sender titleForState:UIControlStateNormal]; 

    if([title isEqualToString:@"hello"]) 
    { 

     NSString *str=[[NSString alloc] initWithFormat:@"abc"]; 
    } 
    else if([title isEqualToString:@"nothing"]) { 

     NSString *str=[[NSString alloc] initWithFormat:@"def"]; 
    } 
    else if([title isEqualToString:@"heaven"]) 
    { 

     NSString *str=[[NSString alloc] initWithFormat:@"ijk"]; 
    } 

    lab.text=str; 
    [str release]; 
} 

sortie:

warning:unused variable str; 

Répondre

3

Le problème est que dans chaque « puis » clause des différents if déclarations, vous créez une nouvelle variable locale appelée str, assigner à une nouvelle chaîne, puis la variable sort du champ d'application. L'avertissement du compilateur devrait vous cocher ceci: vous écrivez à une variable mais jamais en lisant.

Habituellement, votre code ne serait pas compilé, mais vous avez apparemment une autre variable nommée str dans la portée plus tard. Vos nouvelles définitions de str sont l'ombrage l'ancien: tandis que le nouveau nom str est dans la portée, le nom str se réfère à cette variable, pas l'extérieur, et l'extérieur ne peut pas être mentionné.

La solution consiste à déplacer la déclaration de str jusqu'au début de la fonction. En outre, il est plus simple d'utiliser [NSString stringWithFormat:@"blah"] au lieu de [[NSString alloc] initWithFormat:@"blah"], puisque le premier vous donne un objet autoreleased. Cela vous évite d'avoir à manuellement release plus tard. Notez que l'affectation lab.text=str le conserve car la propriété text de la classe UILabel a le modificateur retain.

-(IBAction)buttonclick:(id)sender 
{ 
    NSString *title=[sender titleForState:UIControlStateNormal]; 
    NSString *str; 

    if([title isEqualToString:@"hello"]) 
    { 
     str=[NSString stringWithFormat:@"abc"]; 
    } 
    else if([title isEqualToString:@"nothing"]) 
    { 
     str=[NSString stringWithFormat:@"def"]; 
    } 
    else if([title isEqualToString:@"heaven"]) 
    { 
     str=[NSString stringWithFormat:@"ijk"]; 
    } 

    lab.text=str; 
} 

Notez également que votre code d'origine, vous avez eu à la fois une corruption de fuite de mémoire et de la mémoire - puisque vous allouent une chaîne, puis perdre une référence à elle (par la nouvelle variable locale str va hors de portée) sans le libérer, puis vous appelez release une fois de plus sur la variable externe str. Le déplacement de la déclaration str vers le haut de la fonction corrige les deux problèmes.

Je suppose également que vos chaînes de format sont plus compliquées que les chaînes simples. Si vous attribuez des chaînes constantes telles que "abc", alors bien sûr, il est beaucoup plus simple de faire [email protected]"abc" au lieu de str=[NSString stringWithFormat:@"abc"].

5

Ne pas utiliser le titre des boutons pour différencier entre vos boutons. Cela ne fonctionnerait pas si vos boutons devaient être localisés. Utilisez des actions différentes ou utilisez la balise pour les différencier.

L'avertissement est l'indice de ce que vous faites mal dans ce cas. Une variable locale n'est visible qu'à l'intérieur de la portée déclarée. Votre ligne lab.text = str définit donc lab.text sur une chaîne définie ailleurs, soit une variable statique, soit une variable d'instance. Voici ce que vous pouvez faire à la place:

NSString *str; 

switch ([sender tag]) { 
    case FirstButtonTag: 
    str = @"abc"; 
    break; 
    case SecondButtonTag: 
    str = @"def"; 
    break; 
    case ThirdButtonTag: 
    str = @"ijk"; 
    break; 
} 

lab.text = str;