2010-09-13 31 views
1

我有一个应用程序,我正在写这将需要下载很多图像,可能是10,000。现在我可以在内存不足和应用程序崩溃之前达到大约3000,这取决于图像文件的大小。我正在下载后台线程并向用户显示进度。下载大量图片ipad - 内存泄露?

我写了一个帮助类,我正在访问做这个,并想知道如果这是我的问题所在,我只是泄漏内存。

这里是我的循环,下载图像 - 这是在后台线程上运行,这是所有内部的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]; 
       } 
      } 

这里是我的助手类:

-(void) downloadImages:(NSString *)ItemSKU withManufacturer: (NSString *) aManufacturerID{ 

    NSData *imageData = 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; 
} 

仍在尝试去了解一些这些概念。

回答

2

您是否尝试过构建和分析?这可能有帮助。还玩弄乐器。最后,我建议使用这些NSOperationQueue。这样你就可以并行执行它们。此外,你的AutoReleasePool可能不会自动释放任何东西,直到控制权返回主线程。

+0

是的,它看起来像我回到主线程后,一切都得到释放。我将不得不将它们分成小块并运行一系列后台线程。 – Slee 2010-09-14 01:00:30

+0

+1表示操作队列。它是为这样的东西而建造的。 – 2010-09-14 02:54:22

1

您正在使用的每个工厂方法(stringWith *,stringBy *,URLwith *,dataWith *等)都会返回一个自动释放对象,其池在该循环结束之前不会清空。试一试alloc init,然后release完成。你应该看到更好的结果。

+0

似乎在帮助 - 谢谢你! – Slee 2010-09-14 02:12:44

1

戴夫说得很对...使用NSInvocationOperation。 wuld解决了问题,而不是将代码拆分成块。这里是我使用的示例

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]; 
      }