I read almost every Question here on SO about memory management that involves NSStrings, but I can’t really solve this problem.
@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
A UISegmentedControl with an IBAction linked to:
- (IBAction) changeText:(id)sender
{
if(transcriptionSelector.selectedSegmentIndex == 1)
[transcription setText:diplomaticTranscription];
else
[transcription setText:criticalTranscription];
}
When I change the value of the UISegmentControl (first thing right after loading, nothing else runs), I run into this error (NSZombieEnabled=YES):
2011-07-07 01:10:43.639 Transcribe[404:707] *** -[CFString length]: message sent to deallocated instance 0x1189300
I can’t see anything relevant in the backtrace. Without NSZombieEnabled criticalTranscription just points to random arrays or something else. There is no further usage of the variable or any releases.
I ran analyze without any suspicious leaks.
What’s the problem?
The problem is that you are overwriting a reference to a string that you own with one that you don’t own.
However, don’t use this approach, because it pollutes the autorelease pool with unnecessary strings. Instead, use a mutable string and append strings to the single mutable string instance.
Also, in order to utilise the property’s built-in memory management, you need to use
self.criticalTranscriptionand not justcriticalTranscription. Without theself., you are using the instance variable directly.