Давление памяти из-за загрузки и сохранения изображений

К счастью, я знаю, откуда возникает проблема с нехваткой памяти, и я попробовал несколько методов, таких как обертывание блока в блоке @autorelease и установка объектов в nil, но все еще безуспешно.

Извините за сброс слишком большого количества кода здесь, я попытался сократить его до самого необходимого. Вот код для загрузки и сохранения изображений:

NSMuttableArray *photosDownOps = [NSMuttableArray array];
NSURL *URL = [...];
NSURLRequest *request = [...];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFImageResponseSerializer serializer];

[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {    
    dispatch_queue_t amBgSyncQueue = dispatch_queue_create("writetoFileThread", NULL);
    dispatch_async(amBgSyncQueue, ^{
        [self savePhotoToFile:(UIImage *)responseObject usingFileName:photo.id];
    });    
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    if ([error code] !=  NSURLErrorCancelled)
        NSLog(@"Error occured downloading photos: %@", error);
}];
[photosDownOps addObject:op];

NSArray *photosDownloadOperations = [AFURLConnectionOperation batchOfRequestOperations:photosDownloadOperatons 
                                                                         progressBlock:^(NSUInteger nof, NSUInteger tno) {        
} completionBlock:^(NSArray *operations) {
    NSLog(@"all photo downloads completed");
}];

[self.photosDownloadQueue addOperations:photosDownloadOperations waitUntilFinished:NO];

+ (void) savePhotoToFile:(UIImage *)imageToSave usingFileName:(NSNumber *)photoID{
    @autoreleasepool {
        NSData * binaryImageData = UIImageJPEGRepresentation(imageToSave, 0.6);
        NSString *filePath = [Utilities fullPathForPhoto:photoID];
        [binaryImageData writeToFile:filePath atomically:YES];
        binaryImageData = nil;
        imageToSave = nil;
    }
}

Эта ситуация, хотя случается только с устройствами iPhone 4s, на которых я тестировал, не происходит на моделях iPhone 5.

2 ответа

Мне удалось решить эту проблему путем расширения NSOperation и внутри основного блока сразу же после получения данных, которые я записываю в файл:

- (void)main{
    @autoreleasepool {
        //...
        NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageUrl];        
        if (imageData) {
            NSError *error = nil;
            [imageData writeToFile:imageSavePath options:NSDataWritingAtomic error:&error];
        }
        //...
    }
}

Этот объект NSOperation был тогда добавлен NSOperationQueue, который я уже имел.

Попробуйте создать свой собственный класс для загрузки изображения с помощью NSUrlConnection и в методе делегата добавьте эти данные в ваш файл, просто посмотрите код ниже

-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {

NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:aPath]; 
[fileHandle seekToEndOfFile]; 
[fileHandle writeData:data]; 
[fileHandle closeFile];

}

Это поможет вам в управлении памятью, так как все загружаемые данные не нужно кэшировать.

Другие вопросы по тегам