2009-09-09 3 views
2

У меня есть три кнопки с названием (под названием) hello, ничего, небеса и одна метка (лаборатория IBOutlet UIlabel). Я хочу отобразить три сообщения diff для трех щелчков кнопки diff. Но следующий код не смог выполнить это. Может ли кто-нибудь предложить какую-либо идею?Объектив c Сравнение 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]; 
} 

выход:

warning:unused variable str; 

ответ

3

Проблема заключается в том, что в каждом «затем» п различных if заявления, вы создаете новую локальную переменную с именем str, назначая его на новую строку, а затем переменная выходит за рамки. Предупреждение о компиляторе должно указывать на вас: вы пишете переменную, но не читаете ее.

Как правило, ваш код не будет компилироваться, но, по-видимому, у вас есть другая переменная с именем str в дальнейшем. Ваши новые определения str: shadowing старый: в то время как новое имя str находится в области видимости, имя str относится к этой переменной, а не к внешней, и к внешней нельзя ссылаться.

Решение заключается в перемещении объявления str в верхней части функции. Кроме того, проще использовать [NSString stringWithFormat:@"blah"] вместо [[NSString alloc] initWithFormat:@"blah"], так как первый дает вам автореализованный объект. Это избавит вас от необходимости вручную указывать release. Обратите внимание, что назначение lab.text=str сохраняет его, поскольку свойство text класса UILabel имеет модификатор 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; 
} 

отметить также, что с исходным кодом, вы имели и утечка памяти и памяти с коррупцией - так как вы были выделения строки, а затем потерять ссылку на него (по новой локальной переменной str из области видимости), не выпуская его, а затем вы вызывали release дополнительное время на любую внешнюю переменную str. Перемещение объявления str в начало функции устраняет обе проблемы.

Я также предполагаю, что ваши строки формата сложнее, чем простые строки. Если вы на самом деле назначаете постоянные строки, такие как "abc", то, конечно, гораздо проще просто сделать [email protected]"abc" вместо str=[NSString stringWithFormat:@"abc"].

5

Не используйте название кнопки, чтобы различать кнопки. Это не сработает, если ваши кнопки будут локализованы. Либо используйте разные действия, либо используйте тег, чтобы отличать их.

Предупреждение - это ключ к тому, что вы делаете неправильно в этом случае. Локальная переменная видна только в пределах области, которую она объявила, поэтому ваша строка lab.text = str фактически устанавливает lab.text для str, которая определена в другом месте, либо статическая переменная, либо переменная экземпляра. Вот то, что вы могли бы сделать вместо:

NSString *str; 

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

lab.text = str; 
Смежные вопросы