downloading large amount of images ipad - memory leak?
I am have an app I am writing that will need to download alot of images, possibly 10,000. Right now I can get to about 3000 before I run out of memory and the app crashes, just depends on the image files sizes. I am downloading them on a background thread and showing the progress to the user.
I wrote a helper class thatI am accessing to do this and wondering if that is where my problems lie and I am just leaking memory.
Here is my loop that downloading the images - this is running on a background thread, this is all inside an NSAutoReleasePool:
for (int j=0; j < [items count]; j++)
{
ImagesHelper *helper = [[ImagesHelper alloc]init];
[helper downloadImages: [[items objectAtIndex:j] valueForKey:@"ItemSKU"] withManufacturer: [[manufacturers objectAtIndex:i] ManufacturerID]];
[helper release];
if (j%50==0) { //this notifies the user of progress
statusMessage = [NSString stringWithFormat:@"Downloading images: %@.jpg (%d of %d)", [[items objectAtIndex:j] valueForKey:@"ItemSKU"],j+1, [items count]];
[self performSelectorOnMainThread:@selector(setStatus) withObject:nil waitUntilDone:YES];
}
}
Here is my helper class:
-(void) downloadImages:(NSString *)ItemSKU withManufacturer: (NSString *) aManufacturerID{
NSData *imageDa开发者_如何学Cta = nil;
NSData *imageDataLarge=nil;
NSString *fileName = [NSString stringWithFormat:@"%@_tn.jpg", [ItemSKU stringByReplacingOccurrencesOfString:@" " withString:@""]];
NSString *fileNameLarge = [NSString stringWithFormat:@"%@_lg.jpg", [ItemSKU stringByReplacingOccurrencesOfString:@" " withString:@""]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *savePath = [documentsPath stringByAppendingPathComponent:fileName];
NSString *savePathLarge = [documentsPath stringByAppendingPathComponent:fileNameLarge];
/* go get the image */
NSString *URL = [NSString stringWithFormat:kProductImagesURL,aManufacturerID, fileName];
NSString *URLLarge = [NSString stringWithFormat:kProductImagesURL,aManufacturerID, fileNameLarge];
NSLog(@"Going to get the file: %@",URL);
imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:URL]];
if (imageData!=nil) {
[imageData writeToFile:savePath atomically:YES];
}
imageDataLarge = [NSData dataWithContentsOfURL:[NSURL URLWithString:URLLarge]];
if (imageDataLarge!=nil) {
[imageDataLarge writeToFile:savePathLarge atomically:YES];
}
imageData = nil;
imageDataLarge=nil;
}
Still trying to get ahold of some of these concepts.
Have you tried doing Build and Analyze? That might help. Also play around with Instruments. Lastly, I'd recommend using NSOperationQueue for these. That way you can do them in parallel. Additionally, your AutoReleasePool might not autorelease anything until control returns to the main thread.
Every single one of those factory methods you're using (stringWith*, stringBy*, URLwith*, dataWith*, etc.) is returning an autoreleased object whose pool won't empty until the end of the loop. Try alloc init
on the stuff and then release
as soon as you're finished with it. You should see better results.
Dave said it correctly... Use NSInvocationOperation
. tht wuld fix the issue instead of splitting the code in chunks. here is the sample i used
NSOperationQueue *downloadQueue = [NSOperationQueue new];
for (Product *cProduct in productsMasterArray)
{
NSInvocationOperation *downloadOperation = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(downloadImages:)
object:cProduct.ITEM_CODE];
[downloadQueue addOperation:downloadOperation];
[downloadOperation release];
}
精彩评论