Where is the leak in my NSXMLParser code?
I have set up an NSXMLParser to parse through a Twitter feed, but I am getting memory leaks, and after sitting through using instruments about a hundred times I can't figure out where it is! Below is my NSXMLParser code that parses w开发者_JS百科hen ASIHTTPRequest receives data back.
-(void)ProcessAndParse{
NSURL *url = [config urlForFeed:@"Twitter"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSData *responseData = [request responseData];
myparser = [[NSXMLParser alloc] initWithData:responseData];
[myparser setDelegate:self];
[myparser setShouldResolveExternalEntities:YES];
[myparser parse];
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
currentElement = [elementName copy];
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
}
-(void)parserDidEndDocument:(NSXMLParser *)parser{
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
}
I know there is quite a bit missing here but I am trying to stop this leak before I go on any further. It seems to center around the currentElement = [elementName copy];
in the didStartElement method.
You need to release the previous element, before assigning a new one for currentElement, otherwise the old element won't have any other references and it will be leaked. So you can do this:
[currentElement release];
currentElement = [elementName copy];
Alternatively you can declare your ivar currentElement property as copy, and simply do this:
//This releases previous value, and copies the new Value.
self.currentElement = elementName;
Based on your comments in Oscar's answer, you have currentElement as a property of your delegate class. I see two problems in your code:
You are creating an XML parser and never releasing it. To solve that do this:
myparser = [[[NSXMLParser alloc] initWithData:responseData] autorelease];
You are leaking the currentElement property. To solve that do this:
In your header file make sure your property is defined with the retain keyword
@property (nonatomic, retain) NSString * currentElement;
In your implementation file, make proper use of your property
self.currentElement = elementName;
That should fix all issues.
Looks like you are allocating memory for currentElement in didStartElement but I don't see any place where you release it. It also looks like you are allocating memory for the parser but not releasing it in requestFinished
The code does seem incomplete. To take a stab in the dark, though, I see two allocations and no releases:
myparser = [[NSXMLParser alloc] initWithData:responseData];
and...
currentElement = [elementName copy];
Both the alloc return a retained object, which you would need to release.
精彩评论