views:

1559

answers:

7

Memory leak problem - NSConcreteData

// to set tip - photo in photo frame    
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:pathOfThumbNail]];
UIImage *cellThumbImg;
if([data length]>0){ cellThumbImg=[UIImage imageWithData:data];} else { cellThumbImg=[UIImage imageNamed:@"130X90.gif"]; }
UIImageView *imgView=[[UIImageView alloc]initWithImage:cellThumbImg]; imgView.frame=photoFrame;
(cellThumbImg.size.height>=58 || cellThumbImg.size.width>=58 ) ? [imgView setContentMode:UIViewContentModeScaleToFill] : [imgView setContentMode:UIViewContentModeCenter] ;
[cell.contentView addSubview:imgView]; 
[imgView release];

my question is very much similar to this question,

http://stackoverflow.com/questions/280053/iphone-memory-leak-nsdata-datawithcontentsofurl-uiwebview

Even, I have added following code to my Application Did Finished Launching, given below. Following code is for setting sharedCache memory with zero capacity. It will almost remove the NSConcreteData leak in my application. However memory leaks.

- (void)applicationDidFinishLaunching:(UIApplication *)application {       
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];
[window makeKeyAndVisible];
}

i could not find any solution for this kind of question from stack overflow.

If you can answer, i will be thankful to you.

Thanks in advance.

+4  A: 

Your release message is spelled wrong, you typed relaese but it's release. I figure that's just a problem in the code you typed for this question though.

Second. You don't need the first alloc init chain message. All you need is:

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]];

Granted, I don't know if that call is actually correct, but I do know that it returns an auto-released NSData object meaning your previous alloc init would leak.

Jorge Israel Peña
@Blaenk - Sir, Please check out the correction in my Question. I am having the same problem. Even after Applying your suggested logic, I am finding the same memory leak problem.
sugar
+8  A: 

You have three lines, lets break them down

1. NSData *imageData = [[NSData alloc] init];
2. imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]];
3. [imageData release];

Line 1: allocate and init a new NSData. This NSData will have a reference count of +1

Line 2: get data from internet and place in a NSData. This sets the variable used Line 1 to the new NSData (which is set to autorelease) hiding the NSData alloced and inited on Line 1

Line 3: will release the NSData received on Line 2.

You could remove Line 1 and 3 and just add the variable declaration to Line 2. Because it is autoreleased it will be release by the eventloop later...

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"www.xyz.abc.com"]];

I suggest you read the Memory Management sections here

epatel
@ePatel - Sir, Please check out the correction in my Question. I am having the same problem. Even after Applying your suggested logic, I am finding the same memory leak problem.
sugar
+2  A: 

I had issues with this as well in my Large project. After working with an Apple engineer on trying to locate the leaks, he finally asked the main Apple dev team behind NSURLConnection. They basically said that there is an internal cache that is not clearable at all in NSURLConnection and it was a known issue.

So I set out looking for alternatives. I found ASIHTTPConnection (link below) which works off of CFNetwork. It is designed to be a drop-in replacement for NSURLConnection, plus a bunch of other awesome goodies like downloading to disk instead of memory, download resuming, progress bar callbacks etc..

I have used it in all my projects and have never had any issues or complaints. An, in answer to your question, this is how I got rid of those memory leaks.

http://allseeing-i.com/ASIHTTPRequest/

coneybeare
+5  A: 

Whenever we use dataWithContentOfURL we have to enclose it with NSAutoReleasePool, like the following:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

// ** Your Operations **

NSData *data = [NSData dataWithContentsOfURL:someURL];

// ** Your Operation **

[data autorelease];
[pool release];

This applies even for NSURLRequest and NSURLConnection.

The problem is with the compiler itself and the above is the only method to solve the problem.

This is the answer. Great.
sugar
+2  A: 

@Naveen your solution does not seem to work for me.

I tried the following code but it crashes my app.

NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc]init];

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[planDictionary objectAtIndex:indexPath.row] objectForKey:@"url"]]];

if (imageData!=nil) {

imageForData = [UIImage imageWithData:imageData];

}else {

imageForData = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Plans-Default-image" ofType:@"jpg"]];

}

UIImageView *imageView = [[UIImageView alloc] initWithImage:imageForData];

imageView.frame = frame;

[cell.contentView addSubview:imageView];

[imageData autorelease];

[myPool release];

Hitesh Manchanda
A: 

I am also using the same code but it has memory leaks......... Do you know why? (Naveen)

+1  A: 

@hitesh: sorry for the late reply , but i can see the problem in your code

(....)

NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[planDictionary objectAtIndex:indexPath.row] objectForKey:@"url"]]];

(.....) [imageData autorelease]; // -> this is not required

Since imagedData get's the data from the class method (method called from the class name) which are auto released, you need not call that method , i tried your code by removing that line and it worked for me.

Also look out for a leak in your code,

UIImageView *imageView = [[UIImageView alloc] initWithImage:imageForData];

imageView.frame = frame;

[cell.contentView addSubview:imageView];

[imageView release]; // This was missing , you have to release this because after adding imageView as subview into cell.contentView its retain count is increased.

This must sole @Dragon's problem as well i guess.

RVN