Objective-C:上传太多图像内存压力导致应用程序退出

时间:2014-07-30 18:07:58

标签: objective-c memory file-upload uiimagepickercontroller

我正在使用QBImagePicker来允许多个图片上传。它适用于最多25个图像被下载,但更多,并且应用程序将在上传时退出内存压力。我想允许无限图像上传,并且不确定如何在存储器不成问题的情况下这样做(即可能在每次保存后清除内存)。这是我保存图像的方法(从主QBImagePickerController方法中的循环调用以保存所有选定的图像):

- (void) saveTheImage:(UIImage *)image fileName:(NSString *)name width:(CGFloat) width height:(CGFloat) height quality:(CGFloat) quality extension:(int)fileNumberExtension
{
UIImage *resizedImage = [self resizeImage:image width:width height:height]; //this is a simple method I have to resize the image sent from the picker
NSData *data = UIImageJPEGRepresentation(resizedImage, quality); //save as a jpeg
NSString *fileName = [NSString stringWithFormat:@"%@%d", name, fileNumberExtension]; //set the filename
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; //will be saved in documents
NSString *tempPath = [documentsDirectory stringByAppendingPathComponent:fileName]; //with the filename given

//create a block operation to save
NSBlockOperation* saveOp = [NSBlockOperation blockOperationWithBlock: ^{
    [data writeToFile:tempPath atomically:YES];
}];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:saveOp];
}

提前致谢!

修改

调整图片大小的方法:

- (UIImage *) resizeImage:(UIImage *)image width:(CGFloat) width height:(CGFloat) height
{
UIImage *resizedImage;
CGSize size = CGSizeMake(width, height);
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
[image drawInRect:CGRectMake(0, 0, width, height)];
resizedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return resizedImage;
}

编辑2

其他方法:

- (void) imagePickerController:(QBImagePickerController *)imagePickerController didSelectAssets:(NSArray *)assets
{
for (int i=0;i<assets.count;i++)
{
    ALAssetRepresentation *rep = [[assets objectAtIndex:i] defaultRepresentation];
    CGImageRef iref = [rep fullResolutionImage];
    UIImage *pickedImage = [UIImage imageWithCGImage:iref scale:[rep scale] orientation:(UIImageOrientation)[rep orientation]];
    int fileNumberExtension = [self getHighestImageNumber] + 1; //new images all have a higher file name
    //set the ratio (width of image is 294)
    CGFloat ratio = pickedImage.size.width / 294;
    CGFloat newHeight = pickedImage.size.height / ratio;

    if (newHeight < 430) //image is too wide
    {
        [self saveTheImage:pickedImage fileName:@"img" width:294 height:newHeight quality:0.8f extension:fileNumberExtension];
    }
    else //if the image is too narrow
    {
        //set the ratio (height of image is 430)
        CGFloat ratio = pickedImage.size.height / 430;
        CGFloat newWidth = pickedImage.size.width / ratio;

        [self saveTheImage:pickedImage fileName:@"img" width:newWidth height:430 quality:0.8f extension:fileNumberExtension];
    }

    [self saveTheImage:pickedImage fileName:@"thm" width:78 height:78 quality:0.0f extension:fileNumberExtension]; //save the thumbnail
}

[self dismissImagePickerController];
}

- (void)dismissImagePickerController
{
[self dismissViewControllerAnimated:YES completion:nil];
}

- (void) addImageClicked
{
QBImagePickerController *imagePickerController = [[QBImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.allowsMultipleSelection = YES;
imagePickerController.maximumNumberOfSelection = 20; //allow up to 20 photos at once
imagePickerController.filterType = QBImagePickerControllerFilterTypePhotos;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:imagePickerController];
[self presentViewController:navigationController animated:YES completion:nil];
}

2 个答案:

答案 0 :(得分:1)

通过在此方法中使用@autoreleasepool在我的for循环中添加来解决此问题:

- (void) imagePickerController:(QBImagePickerController *)imagePickerController didSelectAssets:(NSArray *)assets

This thread非常有用。

答案 1 :(得分:0)

您有内存泄漏。泄漏通常不会发生,因为ARC为您照顾它。 (每次使用完图像后,它都会从内存中清除)。但是,NOT ALL对象由ARC控制。有些对象类型(如CGColorSpaceRef等)需要手动释放。

您可以通过在Xcode中运行静态分析来检查这一点。在顶部菜单栏中,选择Product -> Analyze。如果有需要释放物品的地方,它会告诉你。

要释放对象,请执行以下操作:

CGColorSpaceRelease(ref); //where ref is a CGColorSpaceRef.
CGImageRelease(iref); //where iref is a CGImageRef.

或与您的对象相关的相应方法。