0

I am having some difficulty dealing with memory leaks in the following code.

Using the leaks instrument within XCode, which shows up the memory leaks within some of my code that is used for rss parsing.

I am using XCode 4, and releasing the allocations at the foot of the code. I have tried adding releases to each local section which causes crashes or the program to stop working.

Any help of advice much appreciated!!

The code which causes the leaks:

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSString * errorString = [NSString stringWithFormat:@"Unable to download story feed from web site (Error code %i )", [parseError code]];
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@"Error loading content" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
currentElement = [elementName copy];
if ([elementName isEqualToString:@"item"]) {
item = [[NSMutableDictionary alloc] init];
currentImage = [[NSMutableString alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
}
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"item"]) {
[item setObject:currentImage forKey:@"media"];
[item setObject:currentTitle forKey:@"title"];
[item setObject:currentLink forKey:@"link"];
[item setObject:currentSummary forKey:@"summary"];
[item setObject:currentDate forKey:@"date"];
[stories addObject:[item copy]];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([currentElement isEqualToString:@"media"]) {
[currentImage appendString:string];
} else if ([currentElement isEqualToString:@"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:@"link"]) {
[currentLink appendString:string];
} else if ([currentElement isEqualToString:@"description"]) {
[currentSummary appendString:string];
} else if ([currentElement isEqualToString:@"pubDate"]) {
[currentDate appendString:string];
}
}

And the releasing later on:

- (void)dealloc {
[currentElement release];
[rssParser release];
[stories release];
[item release];
[currentImage release];
[currentTitle release];
[currentDate release];
[currentSummary release];
[currentLink release];
[super dealloc];
}
Mark Adams
  • 30,776
  • 11
  • 77
  • 77
R2D2
  • 2,620
  • 4
  • 24
  • 46

2 Answers2

0

Change the following:

UIAlertView * errorAlert = [[[UIAlertView alloc] initWithTitle:@"Error loading content" message:errorString delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] autorelease];

This code should be executed only once:

item = [[NSMutableDictionary alloc] init];
currentImage = [[NSMutableString alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
d.lebedev
  • 2,305
  • 19
  • 27
  • Is it possible to autorelease these items? – R2D2 Dec 02 '11 at 08:29
  • @Richard - yes, it is possible, and don't forget to remove them from -dealloc method in this case – d.lebedev Dec 02 '11 at 08:51
  • I have set this as the accepted answer, as autoreleasing the lines above did help, but I am still having leaks from the rssParser. This may be a known Apple issue, as this other post has the same issue http://stackoverflow.com/questions/1598928/nsxmlparser-leaking – R2D2 Dec 05 '11 at 23:37
  • can you also answer the following http://stackoverflow.com/questions/8860576/how-to-remove-parsing-and-nsplaceholdermutablestring-frame-leaks-in-iphone. thanks in advance – Navnath Memane Jan 17 '12 at 12:11
0

At the start of each didStartElement: method new instances are boing created yet only releases once when the class is dealloc'ed. Thus, as suing that didStartElement: is called more than once there is a build-up of instances of the string objects.

Probably what you want is to create these instances once at the instantiation of the class and then append to them as elements are encountered.

In any event release for each allocation.

zaph
  • 111,848
  • 21
  • 189
  • 228
  • Should probably release the items in the didEndElement method providing that the ended element is item? – max_ Dec 01 '11 at 22:20
  • @XcodeDev That depends on the desired life, one would assume that data will be accumulated somehow for use after the parse is complete. – zaph Dec 01 '11 at 22:36
  • Agreed, but I would go a bouts it in a different way; create an Item object and then set the relevant variables of the Item with respective data before adding it to an NSMutableArray of items. – max_ Dec 01 '11 at 22:40
  • I assume that didStartElement is being called to fill each row of the table showing the rss posts, so that it will be called for each row, and therefore multiple times. Can you suggest any code snippet that would be better for doing this part of the code more cleanly? – R2D2 Dec 02 '11 at 08:28