NSXMLParser refresh leak - iphone

I have strange problem with my app.
When I open my app it parses an RSS feed and displays the results in a tableview and there are no leaks BUT if I press my refresh button it leaks (a lot) :(
My Project: Link
Code:
viewDidLoad
UIBarButtonItem *ShareButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:#selector(tableView_ReFresh)];
self.navigationItem.rightBarButtonItem = ShareButton;
[ShareButton release];
viewDidAppear
if ([stories count] == 0) {
NSURL *path = [[NSURL alloc] initWithString:#"http://feeds.feedburner.com/TheAppleBlog"];
[self parseXMLFileAtURL:path];
[path release];
}
tableView_ReFresh
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSURL *path = [[NSURL alloc] initWithString:#"http://feeds.feedburner.com/TheAppleBlog"];
[self parseXMLFileAtURL:path];
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
[path release];
[pool drain];
reloadData
[blogTable reloadData];
parseXMLFileAtURL
stories = [[NSMutableArray alloc]init];
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
NSData *xml = [NSData dataWithContentsOfURL:URL];
rssParser = [[NSXMLParser alloc] initWithData:xml];
[rssParser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser setDelegate:self];
[self.view setNeedsDisplay];
[rssParser parse];
[xml release];
didStartElement
currentElement = [[elementName copy]autorelease];
if ([elementName isEqualToString:#"item"]) {
// clear out our story item caches...
item = [[[NSMutableDictionary alloc] init]autorelease];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentContent = [[NSMutableString alloc] init];
currentPostID = [[NSMutableString alloc] init];
currentCommentLink = [[NSMutableString alloc] init];
currentCommentNum = [[NSMutableString alloc] init];
}
didEndElement
if ([elementName isEqualToString:#"item"]) {
// save values to an item, then store that item into the array...
[item setObject:currentTitle forKey:#"title"];
[item setObject:currentPostID forKey:#"link"];
[item setObject:currentContent forKey:#"Content"];
[item setObject:currentDate forKey:#"date"];
[item setObject:currentCommentLink forKey:#"commentRssLink"];
[item setObject:currentCommentNum forKey:#"commentsNum"];
[stories addObject:[item copy]];
NSLog(#"adding story: %#", currentPostID);
//NSLog(#"adding story: %#", currentContent);
}
foundCharacters
if ([currentElement isEqualToString:#"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:#"guid"]) {
[currentPostID appendString:string];
} else if ([currentElement isEqualToString:#"content:encoded"]) {
[currentContent appendString:string];
} else if ([currentElement isEqualToString:#"pubDate"]) {
[currentDate appendString:string];
} else if ([currentElement isEqualToString:#"wfw:commentRss"]) {
[currentCommentLink appendString:string];
} else if ([currentElement isEqualToString:#"slash:comments"]) {
[currentCommentNum appendString:string];
}
parserDidEndDocument
[blogTable reloadData];
dealloc
[super dealloc];
[currentElement release];
[rssParser release];
[stories release];
[item release];
[currentTitle release];
[currentDate release];
[currentContent release];
[currentPostID release];
[currentCommentLink release];
[currentCommentNum release];
How do I fix this?
Thanks

My guess this is your leak:
stories = [[NSMutableArray alloc]init];
You're releasing stories in your dealloc, which I assume is a property, which I assume you have declared with retain. If I am correct, you should be able to fix this by either doing (A) self.stores = [[NSMutableArray alloc]init]; or (B) by putting [stories release]; before that line.
Assuming your version of Xcode is reasonably up-to-date, if you run your code with Build & Analyze I would guess it would catch this issue.

I think you need to read the documentation about memory management. First of each time you parse you are allocating the NSXMLParser again and then for each "item" element in the XML file you're allocating your strings again without releasing them.
The easiest route, without fully understanding the problem, is to create properties for your ivars and call 'self.ivar =' when you want to assign a new value to them. The generated setters will take care of releasing the memory that the variable was previously pointing to.
I strongly recommend that you read this though:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

Related

Memory Leaks when we are using NSXmlParser in auto Release pool

- (void)main
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
self.workingArray = [NSMutableArray array];
self.descriptionString = [NSMutableString string];
NSXMLParser *parser = [[[NSXMLParser alloc] initWithData:dataToParse] autorelease];
[parser setDelegate:self];
[parser parse];
if (![self isCancelled])
{
// notify our AppDelegate that the parsing is complete
[self.delegate didFinishParsing:self.workingArray];
}
self.workingArray = nil;
self.descriptionString = nil;
self.dataToParse = nil;
[pool drain];
}
in this code when we [parser parse] is called in this line the memory leaks problem is happened.

Incorrect decrement of the reference count of an object that is not owned at this point by the caller

Incorrect decrement of the reference count of an object that is not owned at this point by the caller on iPhone. It is happening with NSString which I clearly init and release within the for loop. I have tried to do the same as an autoreleases string but I get leaks. I assume the culprit is the stringbytrimming call. Any suggestions, by the way this does not leak, but I get the warning in build and analyze. Everything also works fine and the app does not crash.
for(int i=0;i<storyQuantity;i++) {
NSString *imageString = [[NSString alloc] init];
imageString = [[[storiesArray objectAtIndex:i] objectForKey: #"image"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; // must add trimming to remove characters
imageLoader *imageOperation = [[imageLoader alloc] initWithImageURL:imageString target:self action:#selector(didImageLoad:) number:i];
AppDelegate_iPad *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.queue_ addOperation:imageOperation];
[imageOperation release];
[imageString release];
}
UPDATE - added my imageLoader class, which to the best of my knowledge does not have a leak
- (id)initWithImageURL:(NSString *)url target:(id)target action:(SEL)action number:(int)number {
if(self = [super init]) {
_action = action;
_target = target;
_number = number;
if(url == nil) {
return nil;
} else {
_imgURL = [[NSURL alloc] initWithString:[url copy]];
}
}
return self;
}
- (id)main {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
if ([self isCancelled]) {
NSLog(#"OPERATION CANCELLED");
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[pool drain];
return nil;
} else {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSData *imgData = [[NSData alloc] initWithContentsOfURL:_imgURL];
UIImage *image = [[UIImage alloc] initWithData:imgData];
[imgData release];
if ([self isCancelled]) {
NSLog(#"OPERATION CANCELLED");
[image release];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[pool drain];
return nil;
} else {
NSNumber *tempNumber = [NSNumber numberWithInt:_number];
NSDictionary *tempDict = [NSDictionary dictionaryWithObjectsAndKeys:tempNumber, #"number", image, #"image", nil];
[image release];
if([_target respondsToSelector:_action])
[_target performSelectorOnMainThread:_action withObject:tempDict waitUntilDone:NO];
}
}
[pool drain];
return nil;
}
- (void)dealloc {
[_imgURL release];
[super dealloc];
}
Since you are reassigning the imageString variable, the reference to the original object is lost. Why allocate an empty string anyway? Just change the code to
NSString *imageString = [[[storiesArray objectAtIndex:i] objectForKey: #"image"]
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
and remove the [imageString release] and you're good to go.
Don't track reference counts as a way into understanding memory management. It's only going to confuse you. Things manipulate your objects' reference counts from deep in the framework, and if you watch those numbers jump around for (apparently) no reason, you'll just go insane and post a series of increasingly crazy questions here, which we'll then have to deal with. Believe me--we've seen it before.
So just ignore the reference count number, and make sure you're retaining and releasing objects properly.

xml parsing consumes time need efficent way on iphone

How to call main thread ??? i can parse but i cant display data
- (void)viewDidLoad {
//self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.parentViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"10.png"]];
[super viewDidLoad];
[NSThread detachNewThreadSelector:#selector(startTheBackgroundJob) toTarget:self withObject:nil];
}
- (void)startTheBackgroundJob {
NSUserDefaults *getida = [NSUserDefaults standardUserDefaults];
myIDa = [getida stringForKey:#"AppID"];
NSLog(#"#BOOK MARK ");
NSString *ubook = [[NSString alloc] initWithFormat:#"http://www.wapp=%#&action=show",myIDa];
NSLog(#" bookmark %#",ubook);
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//NSString *outputString = [[NSString stringWithString:usearch] stringByAppendingString: UserText];
ubook = [ubook stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"My string is now = %#", ubook);
NSURL *url = [[[NSURL alloc] initWithString:ubook]autorelease];
//NSURL *url= [NSURL URLWithString:outputString];
NSLog(#" bookmark URL IS %#",url);
NSXMLParser *xmlParser = [[[NSXMLParser alloc] initWithContentsOfURL:url] autorelease];
//Initialize the delegate.
XMLParserbookm *parser = [[[XMLParserbookm alloc] initXMLParser]autorelease];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
{
NSLog(#" xml parsed suucess");
//[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
//[self searchTableView];
//mytimer4=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(wipe) userInfo:nil repeats:NO];
}
else{
NSLog(#"eeror");
}
[NSThread sleepForTimeInterval:3];
[self performSelectorOnMainThread:#selector(makeMyProgressBarMoving) withObject:nil waitUntilDone:NO]; // HOW TO CALL MAIN THREAD
[pool release]
}
You can try with
viewDidAppear:, this method is called after you go to a new view. Then at least, you can switch to new view, you should make sure that there is something on the screen in waiting for the xml parsing
Using Thread: You put parsing into another thread and then callback your main thread after you finish, then there will be no block at all

NSXMLParser & memory leaks

I am parsing an XML file using a custom class that instanciates & uses NSXMLParser. On the first call everything is fine but on the second, third and later calls Instruments show tens of memory leaks on certain lines inside didEndElement, didEndElement and foundCharacters functions.
I googled it and found some people having this issue, but I didn't find anything that could really help me.
My Parser class looks like this :
Parser.h
#interface XMLParser : NSObject {
NSMutableArray *data;
NSMutableString *currentValue;
NSArray *xml;
NSMutableArray *videos;
NSMutableArray *photos;
NSXMLParser *parser;
NSURLConnection *feedConnection;
NSMutableData *downloadedData;
Content *content;
Video *video;
BOOL nowPhoto;
BOOL nowVideo;
BOOL finished;
BOOL webTV;
}
-(void)parseXML:(NSURL*)xmlURL;
-(int)getCount;
-(NSArray*)getData;
//- (void)handleError:(NSError *)error;
//#property(nonatomic, retain) NSMutableString *currentValue;
#property(nonatomic, retain) NSURLConnection *feedConnection;
#property(nonatomic, retain) NSMutableData *downloadedData;
#property(nonatomic, retain) NSArray *xml;
#property(nonatomic, retain) NSXMLParser *parser;
#property(nonatomic, retain) NSMutableArray *data;
#property(nonatomic, retain) NSMutableArray *photos;
#property(nonatomic, retain) NSMutableArray *videos;
#property(nonatomic, retain) Content *content;
#property(nonatomic, retain) Video *video;
#property(nonatomic) BOOL finished;
#property(nonatomic) BOOL nowPhoto;
#property(nonatomic) BOOL nowVideo;
#property(nonatomic) BOOL webTV;
#end
Parser.m
#import "Content.h"
#import "Video.h"
#import "Parser.h"
#import <CFNetwork/CFNetwork.h>
#implementation XMLParser
#synthesize xml, parser, finished, nowPhoto, nowVideo, webTV;
#synthesize feedConnection, downloadedData, data, content, photos, videos, video;
-(void)parseXML:(NSURL*)xmlURL {
/*
NSURLRequest *req = [NSURLRequest requestWithURL:xmlURL];
self.feedConnection = [[[NSURLConnection alloc] initWithRequest:req delegate:self] autorelease];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
*/
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
NSXMLParser *feedParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
//NSXMLParser *feedParser = [[NSXMLParser alloc] initWithData:theXML];
[self setParser:feedParser];
[feedParser release];
[[self parser] setDelegate:self];
[[self parser] setShouldResolveExternalEntities:YES];
[[self parser] parse];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:#"articles"]) {
self.finished = NO;
self.nowPhoto = NO;
self.nowVideo = NO;
self.webTV = NO;
if (!data) {
NSMutableArray *tmp = [[NSMutableArray alloc] init];
[self setData:tmp];
[tmp release];
return ;
}
}
if ([elementName isEqualToString:#"WebTV"]) {
self.finished = NO;
self.nowPhoto = NO;
self.nowVideo = NO;
self.webTV = YES;
if (!data) {
NSMutableArray *tmp = [[NSMutableArray alloc] init];
[self setData:tmp];
[tmp release];
return ;
}
}
if ([elementName isEqualToString:#"photos"]) {
if (!photos) {
NSMutableArray *tmp = [[NSMutableArray alloc] init];
[self setPhotos:tmp];
[tmp release];
return;
}
}
if ([elementName isEqualToString:#"videos"]) {
if (!videos) {
NSMutableArray *tmp = [[NSMutableArray alloc] init];
[self setVideos:tmp];
[tmp release];
return;
}
}
if ([elementName isEqualToString:#"photo"]) {
self.nowPhoto = YES;
self.nowVideo = NO;
}
if ([elementName isEqualToString:#"video"]) {
self.nowPhoto = NO;
self.nowVideo = YES;
}
if ([elementName isEqualToString:#"WebTVItem"]) {
if (!video) {
Video *tmp = [[Video alloc] init];
[self setVideo:tmp];
[tmp release];
}
NSString *videoId = [attributeDict objectForKey:#"id"];
[[self video] setVideoId:[videoId intValue]];
}
if ([elementName isEqualToString:#"article"]) {
if (!content) {
Content *tmp = [[Content alloc] init];
[self setContent:tmp];
[tmp release];
}
NSString *contentId = [attributeDict objectForKey:#"id"];
[[self content] setContentId:[contentId intValue]];
return;
}
if ([elementName isEqualToString:#"category"]) {
NSString *categoryId = [attributeDict objectForKey:#"id"];
NSString *parentId = [attributeDict objectForKey:#"parent"];
[[self content] setCategoryId:[categoryId intValue]];
[[self content] setParentId:[parentId intValue]];
categoryId = nil;
parentId = nil;
return;
}
if ([elementName isEqualToString:#"vCategory"]) {
NSString *categoryId = [attributeDict objectForKey:#"id"];
NSString *parentId = [attributeDict objectForKey:#"parent"];
[[self video] setCategoryId:[categoryId intValue]];
[[self video] setParentId:[parentId intValue]];
categoryId = nil;
parentId = nil;
return;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (!currentValue) {
currentValue = [[NSMutableString alloc] initWithCapacity:1000];
}
if (currentValue != #"\n")
[currentValue appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
NSString *cleanValue = [currentValue stringByReplacingOccurrencesOfString:#"\n" withString:#""] ;
if ([elementName isEqualToString:#"articles"]) {
self.finished = YES;
//[content release];
}
if ([elementName isEqualToString:#"article"]) {
[[self data] addObject:[self content]];
[self setContent:nil];
[self setPhotos:nil];
[self setVideos:nil];
/*
[content release];
content = nil;
[videos release];
videos = nil;
[photos release];
photos = nil;
*/
}
if ([elementName isEqualToString:#"WebTVItem"]) {
[[self data] addObject:[self video]];
[self setVideo:nil];
//[video release];
//video = nil;
}
if ([elementName isEqualToString:#"title"]) {
//NSLog(#"Tit: %#",cleanValue);
[[self content] setTitle:cleanValue];
}
if ([elementName isEqualToString:#"vTitle"]) {
[[self video] setTitle:cleanValue];
}
if ([elementName isEqualToString:#"link"]) {
//NSURL *url = [[NSURL alloc] initWithString:cleanValue] ;
[[self content] setUrl:[NSURL URLWithString:cleanValue]];
[[self content] setLink: cleanValue];
//[url release];
//url = nil;
}
if ([elementName isEqualToString:#"vLink"]) {
[[self video] setLink:cleanValue];
[[self video] setUrl:[NSURL URLWithString:cleanValue]];
}
if ([elementName isEqualToString:#"teaser"]) {
NSString *tmp = [cleanValue stringByReplacingOccurrencesOfString:#"##BREAK##" withString:#"\n"];
[[self content] setTeaser:tmp];
tmp = nil;
}
if ([elementName isEqualToString:#"content"]) {
NSString *tmp = [cleanValue stringByReplacingOccurrencesOfString:#"##BREAK##" withString:#"\n"];
[[self content] setContent:tmp];
tmp = nil;
}
if ([elementName isEqualToString:#"category"]) {
[[self content] setCategory:cleanValue];
}
if ([elementName isEqualToString:#"vCategory"]) {
[[self video] setCategory:cleanValue];
}
if ([elementName isEqualToString:#"date"]) {
[[self content] setDate:cleanValue];
}
if ([elementName isEqualToString:#"vDate"]) {
[[self video] setDate:cleanValue];
}
if ([elementName isEqualToString:#"thumbnail"]) {
[[self content] setThumbnail:[NSURL URLWithString:cleanValue]];
[[self content] setThumbnailURL:cleanValue];
}
if ([elementName isEqualToString:#"vThumbnail"]) {
[[self video] setThumbnailURL:cleanValue];
[[self video] setThumbnail:[NSURL URLWithString:cleanValue]];
}
if ([elementName isEqualToString:#"vDirectLink"]){
[[self video] setDirectLink: cleanValue];
}
if ([elementName isEqualToString:#"preview"]){
[[self video] setPreview: cleanValue];
}
if ([elementName isEqualToString:#"thumbnail_position"]){
[[self content] setThumbnailPosition: cleanValue];
}
if ([elementName isEqualToString:#"url"]) {
if (self.nowPhoto == YES) {
[[self photos] addObject:cleanValue];
}
else if (self.nowVideo == YES) {
[[self videos] addObject:cleanValue];
}
}
if ([elementName isEqualToString:#"photos"]) {
[[self content] setPhotos:[self photos]];
//[photos release];
//photos = nil;
self.nowPhoto = NO;
}
if ([elementName isEqualToString:#"videos"]) {
[[self content] setVideos:[self videos]];
//[videos release];
//videos = nil;
self.nowVideo = NO;
}
//[cleanValue release];
//cleanValue = nil;
[currentValue release];
currentValue = nil;
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Error" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
-(NSArray*)getData {
return data;
}
-(int)getCount {
return [data count];
}
- (void)dealloc {
[parser release];
//[data release];
//[photos release];
//[videos release];
//[video release];
//[content release];
[currentValue release];
[super dealloc];
}
#end
Somewhere in my code, I create an instance of this class :
XMLParser* feed = [[XMLParser alloc] init];
[self setRssParser:feed];
[feed release];
// Parse feed
NSString *url = [NSString stringWithFormat:#"MyXMLURL"];
[[self rssParser] parseXML:[NSURL URLWithString:url]];
Now the problem is that after the first (which has zero leaks), instruments shows leaks in too many parts like this one (they are too much to enumerate them all, but all the calls look the same, I made the leaking line bold) :
in didEndElement :
if ([elementName isEqualToString:#"link"]) {
// THIS LINE IS LEAKING => INSTRUMENTS SAYS IT IS A NSCFString LEAK
[self content] setUrl:[NSURL URLWithString:cleanValue]];
[[self content] setLink: cleanValue];
}
Any idea how to fix this pealse ?
Could this be the same problem as the one mentioned (as an apple bug) by Lee Amtrong here :NSXMLParser Leaking
-(BOOL)fetchAndParseRss{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//To suppress the leak in NSXMLParser
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
NSURL *url = [NSURL URLWithString:GALLERY_FEED];
BOOL success = NO;
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:YES];
[parser setShouldReportNamespacePrefixes:YES];
[parser setShouldResolveExternalEntities:NO];
success = [parser parse];
[parser release];
[pool drain];
return success;
}
As found on this page, you can do the following to get rid of the leaks as well (I've found that you don't need the setMemoryCapacity or setDiskCapacity calls):
NSData *xml = [NSData
dataWithContentsOfURL: [NSURL
URLWithString:#"http://some-xml-url.com/my.xml"]];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xml];

Can anyone identify the leakage , help?

I have developed my iPhone application and now I am testing it with instruments to find memory leakages .
I have my appDelegate class in which I am fetching data from web service and then parse it then store it in an array..
Here is my applicationDidFinishLaunching method :
UIApplication* app = [UIApplication sharedApplication];
app.networkActivityIndicatorVisible = YES;
serviceURL = [[NSUserDefaults standardUserDefaults] stringForKey:#"readOnly_key"];
NSLog(#"text = %#",serviceURL);
if(serviceURL == nil)
{
//We set the default values from the settings bundle.
//Get the bundle path
NSString *bPath = [[NSBundle mainBundle] bundlePath];
NSString *settingsPath = [bPath stringByAppendingPathComponent:#"Settings.bundle"];
NSString *plistFile = [settingsPath stringByAppendingPathComponent:#"Root.plist"];
NSDictionary *settingsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistFile];
NSArray *preferencesArray = [settingsDictionary objectForKey:#"PreferenceSpecifiers"];
NSDictionary *item;
NSString *textEntry_Key;
NSString *readOnly_Key;
for(item in preferencesArray)
{
//Get the key of the item.
NSString *keyValue = [item objectForKey:#"Key"];
//Get the default value specified in the plist file.
id defaultValue = [item objectForKey:#"DefaultValue"];
if([keyValue isEqualToString:#"textEntry_key"]){
textEntry_Key = defaultValue;
}
NSLog(#"default value = %#",defaultValue);
if([keyValue isEqualToString:#"readOnly_key"])
readOnly_Key = defaultValue;
}
//Now that we have all the default values.
//We will create it here.
NSDictionary *appPrerfs = [NSDictionary dictionaryWithObjectsAndKeys:
textEntry_Key, #"textEntry_key",
readOnly_Key, #"readOnly_key",
nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:appPrerfs];
[[NSUserDefaults standardUserDefaults] synchronize];
}
NSURL *url5 = [[NSURL alloc] initWithString:#"http://192.168.0.150/Nirmal/Service.asmx/searchParameterList"];
//NSURL *url5 = [[NSURL alloc] initWithString:[NSString stringWithFormat:#"%#/Service.asmx/searchParameterList"]];
NSMutableURLRequest* request6=[NSMutableURLRequest requestWithURL:url5];
[request6 setHTTPMethod:#"POST"];
[request6 setTimeoutInterval:10];
//NSURLResponse *response6=nil;
// NSError *err6=nil;
//NSData *data6=[[NSURLConnection sendSynchronousRequest:request6 returningResponse:&response6 error:&err6] retain];
data2=[NSURLConnection sendSynchronousRequest:request6 returningResponse:nil error:nil];
if(data2 == nil)
{
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:#"Alert" message:#"The network is not available.\n Please check the Internet connection." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
else
{
NSXMLParser *xmlParser5 = [[NSXMLParser alloc] initWithData:data2];
//Initialize the delegate.
SearchParameterDataParser *searchParameterDataParser = [[SearchParameterDataParser alloc] initSearchParameterDataParser];
//Set delegate
[xmlParser5 setDelegate:searchParameterDataParser];
//Start parsing the XML file.
#try {
// **the leakage line**
BOOL success1 = [xmlParser5 parse];
if(success1)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
}
#catch (NSException * e) {
NSLog(#"Exception in parsing %# %#",[e name], [e reason]);
}
//[xmlParser5 release];
[searchParameterDataParser release];
//[xmlParser5 release]; //leakage
}
[data2 release];
and this is my parser class :
#import "SearchParameterDataParser.h"
#import "AppDelegate.h"
#import "SearchClass.h"
#implementation SearchParameterDataParser
-(SearchParameterDataParser *)initSearchParameterDataParser{
[super init];
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if([elementName isEqualToString:#"SearchClass"]) {
[appDelegate.tempArray release];
appDelegate.tempArray = [[NSMutableArray alloc] init];
appDelegate.aSearchClass = [[SearchClass alloc]init];
}
NSLog(#"Processing Element: %#", elementName);
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue){
[currentElementValue release];
currentElementValue = [[NSMutableString alloc] initWithString:string];
}
else
[currentElementValue appendString:string];
NSLog(#"Processing Value: %#", currentElementValue);
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:#"SearchClass"]){
[appDelegate.tempArray addObject:appDelegate.aSearchClass];
return;
}
else
[appDelegate.aSearchClass setValue:currentElementValue forKey:elementName];
// [currentElementValue release];
currentElementValue = nil;
}
- (void) dealloc {
[super dealloc];
[aSearchClass release];
[currentElementValue release];
//[self release];
}
#end
I have specified the leakage line in the code .
Can anyone tell me what is going wrong or how can I solve the memory leakage ???????
This is pretty messy, as a suggestion to clean things up a bit, try moving some memory management stuff to accessor methods - your code is littered with -release methods. ie,
instead of:-
if([elementName isEqualToString:#"SearchClass"]) {
[appDelegate.tempArray release];
appDelegate.tempArray = [[NSMutableArray alloc] init];
}
try:-
if([elementName isEqualToString:#"SearchClass"]) {
appDelegate.tempArray = [NSMutableArray array];
}
where
appDelegate has a method
- (void)setTempArray:(NSMutableArray *)value {
if(value!=tempArray){
[tempArray release];
tempArray = [value retain];
}
}
or you can use a #synthesized accessor method to save coding it yourself. As an aside tempArray is a terrible name for an instance variable. Also note that you are releasing the old tempArray each time you make a new one - when does the last instance get cleaned up?
This is still not great as your parser class should not access directly the instance variables in appDelegate. Vardiables tempArray and searchClass should be private, but that is off the point and more of a design issue.
Where does url5 get released?
What is this supposed to do?
if(!currentElementValue){
[currentElementValue release];
}
release currentElementValue if it doesn't exist?
[data2 release];
Did you retain data2?
- (void) dealloc {
[super dealloc];
[aSearchClass release];
[currentElementValue release];
//[self release];
}
i thought aSearchClass was an instance variable on appDelegate?
This might sound like nitpicking but it is much easier to track down leaks if make your code clear and you know exactly what is going on.
You need to release both url5 and xmlParser5, since you've allocated them using alloc.
You should also be wary of calling release on properties, since the standard setters created when you #synthesize an instance variable typically release the previous value of the variable before setting the new value.