2011-07-06 4 views
0

Я читаю почти каждый вопрос здесь о SO об управлении памятью, который связан с NSStrings, но я не могу решить эту проблему.Утечка памяти с помощью NSString

@interface:

@property (nonatomic, retain) NSString *criticalTranscription; 

@implementation: viewDidLoad:

criticalTranscription = [[NSString alloc] init]; 

NSArray *paragraphs = [doc valueForKeyPath:@"critical.text"]; 
for(int i = 0; i < [paragraphs count]; i++) 
{ 
    criticalTranscription = [criticalTranscription stringByAppendingString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 
    criticalTranscription = [criticalTranscription stringByAppendingString:@"\n\n"]; 
} 
[transcription setText:criticalTranscription]; 

@XIB UISegmentedControl с IBAction связан с:

- (IBAction) changeText:(id)sender 
{ 
    if(transcriptionSelector.selectedSegmentIndex == 1) 
    [transcription setText:diplomaticTranscription]; 
    else 
    [transcription setText:criticalTranscription]; 
} 

При изменении значения UISegmentControl (первое, что сразу после загрузка, ничего другого работает), я столкнулся с этой ошибкой (NSZombieEnabled = YES):

2011-07-07 01:10:43.639 Transcribe[404:707] *** -[CFString length]: message sent to deallocated instance 0x1189300 

Я не вижу ничего соответствующего в трассировке. Без NSZombieEnabled criticalTranscription просто указывает на случайные массивы или что-то еще. Дальнейшее использование переменной или каких-либо выпусков не существует.

Я провел анализ без каких-либо подозрительных утечек.

В чем проблема?

+0

Где вы создаете и устанавливаете 'diplomTranscription'? – PengOne

ответ

3

Проблема в том, что вы переписываете ссылку на строку, принадлежащую вам той, которой вы не являетесь.

// you own the empty string returned here 
criticalTranscription = [[NSString alloc] init]; 

NSArray *paragraphs = [doc valueForKeyPath:@"critical.text"]; 
for(int i = 0; i < [paragraphs count]; i++) 
{ 
    // immediately overwrite allocated instance (that you own) 
    criticalTranscription = [criticalTranscription stringByAppendingString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 
    criticalTranscription = [criticalTranscription stringByAppendingString:@"\n\n"]; 
} 

Однако, не используйте этот подход, поскольку он загрязняет пул автозапуска ненужными строками. Вместо этого используйте изменяемую строку и добавьте строки в один экземпляр изменяемой строки.

Кроме того, для использования встроенного управления памятью необходимо использовать self.criticalTranscription, а не только criticalTranscription. Без self. вы используете переменную экземпляра напрямую.

+0

Doh! Ищете уже час! Благодаря! – Patrick

1

В ваш цикл

criticalTranscription = [criticalTranscription stringByAppendingString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 
criticalTranscription = [criticalTranscription stringByAppendingString:@"\n\n"]; 

вы настраиваете criticalTranscription к autoreleased строкового объекта, но не сохраняя его, таким образом, пламенный смерть.

Вы можете оставить его или использовать недвижимость с @property(nonatomic, copy)NSString *criticalTranscription; и использовать собственность, а не ivar.

1

две проблемы:

  • Вы протечки первый экземпляр строки
  • Каждое последующее значение присвоенное ему становится autoreleased

Чтобы исправить это, самый простой способ изменить criticalTranscription на NSMutableString.Тогда вы можете сделать:

criticalTranscription = [[NSMutableString alloc] init]; 

NSArray *paragraphs = [doc valueForKeyPath:@"critical.text"]; 
for(int i = 0; i < [paragraphs count]; i++) 
{ 
    [criticalTranscription appendString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 
    [criticalTranscription appendString:@"\n\n"]; 
} 
[transcription setText:criticalTranscription]; 

... в качестве альтернативы,

[criticalTranscription appendFormat:@"%@\n\n", [[paragraphs objectAtIndex:i] valueForKey:@"p"]]; 

Также обратите внимание, что вам нужно позвонить release на criticalTranscription, как только вы сделали с ним, либо в конце вашего -viewDidLoad или в его соответствует -viewDidUnload.

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