2010-09-13 2 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

+0

+1 для очереди операций. Он был построен для таких вещей. –

1

Каждый один из тех методов, которые вы используете (stringWith *, stringBy *, URLwith *, dataWith * и т. Д.), Возвращает объект с автореализацией, пул пулов которого не будет опущен до конца цикла. Попробуйте alloc init, а затем release, как только вы закончите с ним. Вы должны увидеть лучшие результаты.

+0

, похоже, помогает - спасибо! – Slee

1

Дэйв правильно сказал ... Используйте NSInvocationOperation. tht wuld исправляет проблему, а не разбивает код на куски. здесь используется образец i

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]; 
      } 
Смежные вопросы