Objective c Comparison NSString

I have three buttons named (named) hello, nothing, sky and one label (IBOutlet UIlabel). I want to display three diff messages for three diff button clicks. But the following code failed to accomplish this. Can anyone suggest any idea?

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

      

output:

warning:unused variable str;  

      

+2


source to share


2 answers


The problem is that in each "then" clause of various statements, if

you create a new local variable with a name str

, assigning it to a new line, and then the variable is out of scope. A compiler warning should flag you like this: You write a variable, but you don't read it.

Typically, your code will not compile, but another variable named will appear in the visible scope later str

. Your new definitions str

obscure the old one: while the new name str

is in scope, the name str

refers to that variable, not the external one, and the external cannot be referenced.

The solution is to move the declaration to the str

top of the function. Also, it's easier to use [NSString stringWithFormat:@"blah"]

instead [[NSString alloc] initWithFormat:@"blah"]

, since the former gives you an auto-implemented object. This saves you the hassle of manually release

later. Note that the assignment lab.text=str

preserves it because the text

class property UILabel

has a modifier 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;
}

      

Also note that with the original code you had both a memory leak and memory corruption - as you allocated a string and then lost a reference to it (with a new local variable str

out of scope) without freeing it, and then you took release

extra time for any external variable str

. Moving the declaration str

to the top of the function fixes both problems.

I also assume that your formatted strings are more complex than plain strings. If you are actually assigning constant strings like "abc"

, then of course it is much easier to just str=@"abc"

instead str=[NSString stringWithFormat:@"abc"]

.

+3


source


Don't use the title of the buttons to differentiate your buttons. It won't work if your buttons are localized. Either use different actions or use a tag to distinguish them.

Warning is the key to what you are doing wrong in this case. The local variable is only visible within the scope it has declared, so your lab.text = str line actually sets lab.text for str that is defined elsewhere, either a static variable or an instance variable. Here's what you could do instead:



NSString *str;

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

lab.text = str;

      

+5


source







All Articles