2011-01-26 3 views
0

Я хочу объявить объект NSString для использования в предупреждении, но его фактический контент зависит от различных факторов, определенных некоторой переменной. Мне интересно, как лучше подойти к этому. В большинстве случаев я сделал что-то вроде этого:Как объявить NSString с несколькими возможными значениями

- (void)info { 
    NSString *targetString = [[NSString alloc] init]; 
    switch (self.target) { 
     case 1: 
      targetString = @"ONE"; 
      break; 
     case 2: 
      targetString = @"TWO"; 
      break; 
     case 3: 
      targetString = @"THREE"; 
      break; 
     default: 
      targetString = @""; 
      break; 
    } 

NSString *message = [[NSString alloc] initWithFormat:@"Text: %@", targetString]; 
    UIAlertView *alert = [[UIAlertView alloc] 
          initWithTitle:@"Info" 
          message:message 
          delegate:self 
          cancelButtonTitle:@"Ok!" 
          otherButtonTitles:nil]; 
    alert.tag = kInfoAlert; 
    [alert show]; 
    [alert release]; 
    [targetString release]; 
    [message release]; 
} 

Однако, когда я запускаю это через анализатор сборки, я получаю сообщение, рассказывающее мне строку утечку памяти:

Прежде всего, это говорит:

Значение хранится в '' targetString во его инициализации никогда не читал

Тогда:

Потенциальные утечки объекта выделено на линии 137 и хранятся в 'targetString'

Эти 2 комментария находятся на линии 136 и 137, где линия 136

NSString *targetString = [[NSString alloc] init];

Альтернативой может быть объявление строки как

NSString *targetString; 

и установить его в каждом случае, как

targetString = [NSString stringWithFormat:@"ONE"]; 

и т.д.

Или даже allocing строки в каждом конкретном случае для того, чтобы выпустить его в конце ...

Ну, что бы лучший подход здесь?

Спасибо,

Michael :)

ответ

5

Причина для утечки памяти, потому что вы понапрасну выделения строки с этой строки

NSString *targetString = [[NSString alloc] init]; 

, а затем установить его в буквальном объекте. Определите targetString как nil, потому что, когда вы устанавливаете его на другое значение, например targetString = @"ONE", вы больше не ссылаетесь на пустую строку, которую вы выделили, и это вызывает утечку памяти. Что касается вашего подхода к случаю коммутатора для определения значения, которое является хорошим.

+0

Так что я должен просто объявить его как NSString * targetString, а затем установить его как targetString = @ "ONE"? – Smikey

+0

Не объявляйте его ничтожным.'NSString * targetString = nil;', а затем установите его в литерал в инструкции switch. Также нет необходимости выделять targetString при установке его в строку. – Joe

+0

Что касается строки, которую я устанавливаю, это не простой литерал, т. Е. Мне нужно объявить что-то вроде [[NSString alloc] initWithFormat: @ «Some text plus% @», someString]; Затем я выделяю память. Должен ли я использовать метод удобства? – Smikey

2

Я считаю, что это было бы достаточно:

NSString *targetString = nil; 

И вам не нужно освободить targetString тогда.

0

Как об этом вместо коммутатора:

- (NSString*) stringForIndex: (NSUInteger) index 
{ 
    NSParameterAssert(index < 4); 
    id strings[] = {@"none", @"one", @"two", @"three"}; 
    return strings[index]; 
} 
+0

В этом случае да, но я просто использовал это, чтобы проиллюстрировать более общий случай. Спасибо хоть. – Smikey

Смежные вопросы