资产连接中断或资产死亡(带内存警告)

时间:2015-05-09 07:43:01

标签: ios iphone xcode memory-management ios8.1

我们正试图让用户从他们的相册中导入图片(UIImagePickerController),同时我们正在缩小/调整大于800万像素(iPhone标准)的图片。

但每次导入图片之后或之前,应用都会遇到Connection to assetsd was interrupted or assetsd diedReceived memory warning警告。当Received memory warning仍在寻找要导入的图片时,会弹出UIImagePickerController次警告}。

特别是在iPhone 4S上这更糟糕,请帮助我们优化我们的代码,以便在iPhone 4S或iPad 2等旧设备上运行时不会出现警告和崩溃。

如果我们在使用CoreGraphics缩放/调整图像大小时做错了,请告诉我们。(因为这是使用大量内存的地方)。

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
    {
        UIImage *selectedImage=[info objectForKey:UIImagePickerControllerOriginalImage];
        if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
        {
            [picker dismissViewControllerAnimated:YES completion:nil];
        }
        else
        {
            [popoverController dismissPopoverAnimated:YES];
            [self popoverControllerDidDismissPopover:popoverController];
        }

        // COMPRESSING IMAGE
        NSData   *selectedImageData=UIImageJPEGRepresentation(selectedImage, 0.1);
        UIImage *selectedImageFromData=[UIImage imageWithData:selectedImageData];

        // IMAGE ASPECT RATIO
        CGFloat originalWidth=selectedImageFromData.size.width;
        CGFloat originalHeight=selectedImageFromData.size.height;
        CGFloat myWidth=2048;
        CGFloat myHeight=2048;
        CGFloat widthRatio=myWidth/originalWidth;
        CGFloat heightRatio=myHeight/originalHeight;
        CGFloat dynamicWidth=heightRatio*originalWidth;
        CGFloat dynamicHeight=widthRatio*originalHeight;


        //SCALING UIIMAGE MORE THAN 8 MEGAPIXELS
        if (((selectedImageFromData.size.width>3264) && (selectedImageFromData.size.height>2448)) || ((selectedImageFromData.size.height>3264) && (selectedImageFromData.size.width>2448)))
        {



             // DATA FROM UIIMAGE TO CORE GRAPHICS
             CGImageRef CoreGraphicsImage=selectedImageFromData.CGImage;
            CGColorSpaceRef colorSpace = CGImageGetColorSpace(CoreGraphicsImage);
            CGBitmapInfo bitmapInfo=CGImageGetBitmapInfo(CoreGraphicsImage);
            CGImageGetBitsPerComponent(CoreGraphicsImage);


            // RESIZING WIDTH OF THE IMAGE
            if (originalWidth>originalHeight)
            {


            CGContextRef context=CGBitmapContextCreate(NULL, myWidth, dynamicHeight, CGImageGetBitsPerComponent(CoreGraphicsImage), CGImageGetBytesPerRow(CoreGraphicsImage), colorSpace, bitmapInfo);


            CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
            CGContextDrawImage(context, CGRectMake(0, 0, myWidth, dynamicHeight), CoreGraphicsImage);
            CGImageRef CGscaledImage=CGBitmapContextCreateImage(context);
                UIImage *CGLastimage = [UIImage imageWithCGImage: CGscaledImage];
                NSLog(@"%f",CGLastimage.size.width);
                NSLog(@"%f",CGLastimage.size.height);

                VisualEffectImageVIew.image=CGLastimage;
                BackgroundImageView.image=CGLastimage;
                ForegroundImageView.image=CGLastimage;
            }


            //RESIZING HEIGHT OF THE IMAGE
            if (originalHeight>originalWidth)
            {
                CGContextRef context=CGBitmapContextCreate(NULL, dynamicWidth, myHeight, CGImageGetBitsPerComponent(CoreGraphicsImage), CGImageGetBytesPerRow(CoreGraphicsImage), colorSpace, bitmapInfo);


                CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
                CGContextDrawImage(context, CGRectMake(0, 0, dynamicWidth, myHeight), CoreGraphicsImage);
                CGImageRef CGscaledImage=CGBitmapContextCreateImage(context);
                UIImage *CGLastimage = [UIImage imageWithCGImage: CGscaledImage];

                NSLog(@"%f",CGLastimage.size.width);
                NSLog(@"%f",CGLastimage.size.height);

                VisualEffectImageVIew.image=CGLastimage;
                BackgroundImageView.image=CGLastimage;
                ForegroundImageView.image=CGLastimage;

            }


        }
        else
        {
            NSLog(@" HEIGHT %f",selectedImageFromData.size.height);
            NSLog(@" WIDTH %f",selectedImageFromData.size.width);

        VisualEffectImageVIew.image=selectedImageFromData;
        BackgroundImageView.image=selectedImageFromData;
        ForegroundImageView.image=selectedImageFromData;
        }


    }

记忆报告

在UIImagePickerController中滚动

http://i.stack.imgur.com/qxx62.png

缩放/调整UIImage的大小

http://i.stack.imgur.com/ELCA6.png

1 个答案:

答案 0 :(得分:3)

两点。

首先,您没有释放您创建的对象 - 您正在泄漏大量内存。无论您是否使用ARC,都必须根据每个CG Create 调用调用CGContextRelease或CGImageRelease。

其次,如果您只是想调整大小,使用coregraphics是过度的,请使用UIKit。在我下面使用的代码中,注意使用@autorelease确保在上下文结束后ARC清理对象

- (UIImage *)fitImage:(UIImage *)image scaledToFillSize:(CGSize)size {
    // do not upscale

    @autoreleasepool {
        if( image.size.width <= size.width && image.size.height <= size.height )
            return image;

        CGFloat scale = MIN(size.width/image.size.width, size.height/image.size.height);
        CGFloat width = image.size.width * scale;
        CGFloat height = image.size.height * scale;

        CGRect imageRect;
        // center image
        if( scale != 1.0 ) { // avoid divide by zero?
            if( size.width/image.size.width < size.height/image.size.height ) {
                // height needs to be centered
                imageRect = CGRectMake(0, (size.height-height)/2, width, height);
            } else {
                // width needs to be centered
                imageRect = CGRectMake((size.width-width)/2, 0, width, height);
            }
        }

        UIGraphicsBeginImageContextWithOptions(size, YES, 0);
        [[UIColor CollageBorderUIColor] setFill]; // otherwise it's ugly black fill
        UIRectFill(CGRectMake(0, 0, size.width, size.height));
        [image drawInRect:imageRect];
        UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return newImage;
    }
}