загрузка большого количества изображений ipad - утечка памяти? - PullRequest
1 голос
/ 13 сентября 2010

У меня есть приложение, которое я пишу, и мне нужно будет загрузить много изображений, возможно, 10000. Прямо сейчас я могу получить около 3000, прежде чем у меня не хватит памяти и приложение зависнет, зависит только от размеров файлов изображений. Я загружаю их в фоновом потоке и показываю прогресс пользователю.

Я написал вспомогательный класс, к которому я обращаюсь, и задаюсь вопросом, в этом ли моя проблема, и я просто теряю память.

Вот мой цикл загрузки изображений - он работает в фоновом потоке, все это внутри 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;
}

Все еще пытаюсь овладеть некоторыми из этих концепций.

Ответы [ 3 ]

2 голосов
/ 14 сентября 2010

Вы пробовали делать сборку и анализ?Это может помочь.Также поиграйте с инструментами.Наконец, я бы рекомендовал использовать NSOperationQueue для них.Таким образом, вы можете сделать их параллельно.Кроме того, ваш AutoReleasePool может ничего не делать автоматически, пока управление не вернется в основной поток.

1 голос
/ 26 мая 2011

Дейв правильно сказал ... Используйте NSInvocationOperation. Это поможет исправить проблему, а не разбивать код на части. вот образец, который я использовал

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];
            }
1 голос
/ 14 сентября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...