Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 06-20-2009, 07:14 AM   #1 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 2
Question iPhone memory leak in xml parser

Hi everyone,
I am building an iPhone app that parses a couple of xml files using TouchXML. I have a class XMLParser, which takes care of downloading and parsing the results. I am getting memory leaks when I parse an xml file more than once with the same instance of XMLParser.
Here is one of the parsing methods:

Code:
for(int counter = 0; counter < [item childCount]; counter++) {
	CXMLNode *child = [item childAtIndex:counter];
	if([[child name] isEqualToString:@"PRODUCT"]) 
	{
		NSMutableDictionary *product = [[NSMutableDictionary alloc] 
						init];
		for(int j = 0; j < [child childCount]; j++) {
			CXMLNode *grandchild = [child childAtIndex:j];
			if([[grandchild stringValue] length] > 1) {
				NSString *trimmedString = [[grandchild stringValue] 
				stringByTrimmingCharactersInSet:
				[NSCharacterSet whitespaceAndNewlineCharacterSet]];
				[product setObject:trimmedString 
				forKey:[grandchild name]];
			}
		}
		
		// Add product to current category array
		switch (categoryId) {
			case 0:
				[self.mobil addObject:product];
				break;
			case 1:
				[self.allgemein addObject:product];
				break;
			case 2:
				[self.besitzeIch addObject:product];
				break;
			case 3:
				[self.willIch addObject:product];
				break;
			default:
				break;
		}
		//DebugLog(@"ADD allgemein %@",product);
		[product release];
	}
}
The first time, I parse the xml no leak shows up in instruments, the next time I do so, I got a lot of leaks (NSCFString / NSCFDictionary).
Instruments points me to this line in CXMLNode.m, when I dig into a leaked object:
Code:
theStringValue = [NSString stringWithUTF8String:(const char *)theXMLString];
if ( _node->type != CXMLTextKind )
	xmlFree(theXMLString);
}

return(theStringValue);
I really spent a long time and tried multiple approaches to fix this, but to no avail so far, maybe I am missing something essential?

Any help is highly appreciated, thank you!

Last edited by krille; 06-20-2009 at 07:26 AM.
krille is offline   Reply With Quote
Old 06-20-2009, 11:50 AM   #2 (permalink)
New Member
 
Join Date: Jun 2009
Posts: 2
Lightbulb

I fixed the problem myself. It is nothing wrong with the TouchXML Code - it was kind of stupid, but maybe someone might come across the same thing, so I am going to post it here.

1) I had a mutable array set up as instance variables like this:

Code:
    @interface XMLParser : NSObject {

    // ...  
    NSMutableArray *mobil;  
    // ...  
    }   
    @property(nonatomic, retain) NSMutableArray *mobil;  
    @end
Everytime I wanted to reset and store new data inside the array I did:
Code:
self.mobil = nil;
Which did not what I wanted to do, so this is the better approach:
Code:
[self.mobil removeAllObjects];
2) The dealloc method has to be like this to fix the leaks (because mobil is defined as a property):
Code:
    -(void)dealloc {  
      [mobil release];  
      self.mobil = nil;  
  }
Whew, that has been a lot of work to find out - hope it saves someone else some time :-)
krille is offline   Reply With Quote
Old 11-06-2009, 11:32 AM   #3 (permalink)
krishnan
 
krish's Avatar
 
Join Date: Sep 2009
Location: Chennai
Posts: 38
Send a message via Yahoo to krish
Default Help

Quote:
Originally Posted by krille View Post
I fixed the problem myself. It is nothing wrong with the TouchXML Code - it was kind of stupid, but maybe someone might come across the same thing, so I am going to post it here.

1) I had a mutable array set up as instance variables like this:

Code:
    @interface XMLParser : NSObject {

    // ...  
    NSMutableArray *mobil;  
    // ...  
    }   
    @property(nonatomic, retain) NSMutableArray *mobil;  
    @end
Everytime I wanted to reset and store new data inside the array I did:
Code:
self.mobil = nil;
Which did not what I wanted to do, so this is the better approach:
Code:
[self.mobil removeAllObjects];
2) The dealloc method has to be like this to fix the leaks (because mobil is defined as a property):
Code:
    -(void)dealloc {  
      [mobil release];  
      self.mobil = nil;  
  }
Whew, that has been a lot of work to find out - hope it saves someone else some time :-)


Hi Friend,

I am going through a similar problem. I am also using a custom parser to parse incoming data. But when I check it through Leaks tool, I find the most of the objects I use are leaking. Pleas could you help me?.
krish is offline   Reply With Quote
Old 11-06-2009, 05:33 PM   #4 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 52
Default

[quote=krille;95037]

Your dealloc method should include a call to super dealloc. Leaving that off, and it's pretty easy to do, can cause an object to stick around though the retain count for the object is actually zero.


Example dealloc

Code:
    -(void)dealloc {  
      [mobil release];  
      self.mobil = nil;    
      [super dealloc];
  }

Last edited by Iphoneer; 11-06-2009 at 08:16 PM. Reason: Erase bad info!!!
Iphoneer is offline   Reply With Quote
Old 11-09-2009, 07:32 AM   #5 (permalink)
krishnan
 
krish's Avatar
 
Join Date: Sep 2009
Location: Chennai
Posts: 38
Send a message via Yahoo to krish
Default

[quote=Iphoneer;140330]
Quote:
Originally Posted by krille View Post

Your dealloc method should include a call to super dealloc. Leaving that off, and it's pretty easy to do, can cause an object to stick around though the retain count for the object is actually zero.


Example dealloc

Code:
    -(void)dealloc {  
      [mobil release];  
      self.mobil = nil;    
      [super dealloc];
  }
Hi Friend, I am using a custom XML parser. But even after releasing it it leaks. Please help me. I have provided the code below:



+(id) requestServiceWithInMemoryContext: (NSManagedObjectContext *)managedObjContext NSString *)methodName : (NSDictionary *)params : (RequestTypes)requestType
{
NSURL *url=[self getURL: methodName : params];
HWXMLParser *xmlParser = [[HWXMLParser alloc] initWithContext:managedObjContext RequestType:requestType];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:xmlParser];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
if ( [parser parserError] ) {
NSLog(@"Parse error %@", [parser parserError]);
if(![HWUtility isNetWorkAvailable])
{
[xmlParser release];
[parser release];
return nil;
}
}
[parser release];
[xmlParser saveManagedObjectContext];
returnValue= [xmlParser getParsedResults];
xmlParser=nil;
[xmlParser release];
return returnValue;
}


The returnValue is

id returnValue;


Thank you..
Krishnan.
krish is offline   Reply With Quote
Old 11-09-2009, 09:24 AM   #6 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,086
Default

Code:
HWXMLParser *xmlParser = [[HWXMLParser alloc] initWithContentsOfURL:url];
...
xmlParser=nil;
[xmlParser release];
Release before nil.
__________________
BriTer Ideas LLC - Code review, consulting, development. PM for pricing.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
BrianSlick is offline   Reply With Quote
Old 11-13-2009, 01:41 PM   #7 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 52
Default

Quote:
Originally Posted by BrianSlick View Post
Code:
HWXMLParser *xmlParser = [[HWXMLParser alloc] initWithContentsOfURL:url];
...
xmlParser=nil;
[xmlParser release];
Release before nil.
I disagree.

Why send a release message to a pointer that you know points to nil? I know doing so is harmless, but if you are going to use both statements, wouldn't the reverse order be more logical.
Iphoneer is offline   Reply With Quote
Old 11-13-2009, 01:43 PM   #8 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,086
Default

Quote:
Originally Posted by Iphoneer View Post
I disagree.

Why send a release message to a pointer that you know points to nil? I know doing so is harmless, but if you are going to use both statements, wouldn't the reverse order be more logical.
I think you misread something.
__________________
BriTer Ideas LLC - Code review, consulting, development. PM for pricing.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
BrianSlick is offline   Reply With Quote
Old 11-13-2009, 05:03 PM   #9 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 52
Default

Quote:
Originally Posted by BrianSlick View Post
I think you misread something.

Yes, I seemed to have erred...
Iphoneer is offline   Reply With Quote
Reply

Bookmarks

Tags
iphone, leak, touchxml, xml

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Stats
Members: 158,307
Threads: 89,033
Posts: 379,817
Top Poster: BrianSlick (7,086)
Welcome to our newest member, percent17
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 04:51 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0