Давление памяти из-за загрузки и сохранения изображений
К счастью, я знаю, откуда возникает проблема с нехваткой памяти, и я попробовал несколько методов, таких как обертывание блока в блоке @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];
}
Это поможет вам в управлении памятью, так как все загружаемые данные не нужно кэшировать.