如何释放不再使用的UIImage的内存
我正试图将一些较小的图像合并成一个较大的图像。 该应用程序崩溃,因为它的内存不足,但我不知道如何释放内存后,它使用,所以它一直build立直到应用程序崩溃。
addImageToImage和resizeImage例程看起来是导致崩溃,因为我不能释放内存后,不再需要它的内存。 我在这个项目中使用自动引用计数。 我已经尝试将图像设置为零,但这并不能阻止崩溃。
testImages是在一个从主ViewController调用的类中,而addImageToImage和resizeImage在另一个名为ImageUtils的类中。
有人可以看看这个代码,并向我解释如何正确释放这两个例程分配的内存。 由于项目使用ARC并将它们设置为零,所以我无法在图像上调用发布。
+ (void)testImages { const int IMAGE_WIDTH = 394; const int IMAGE_HEIGHT = 150; const int PAGE_WIDTH = 1275; const int PAGE_HEIGHT = 1650; const int COLUMN_WIDTH = 30; const int ROW_OFFSET = 75; CGSize imageSize = CGSizeMake(PAGE_WIDTH, PAGE_HEIGHT); UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextFillRect(context, CGRectMake(0, 0, imageSize.width, imageSize.height)); UIImage *psheet = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); CGSize collageSize = CGSizeMake(IMAGE_WIDTH, IMAGE_HEIGHT); UIGraphicsBeginImageContextWithOptions(collageSize, YES, 0); CGContextRef pcontext = UIGraphicsGetCurrentContext(); CGContextFillRect(pcontext, CGRectMake(0, 0, collageSize.width, collageSize.height)); UIImage *collage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); float row = 1; float column = 1; int index = 1; int group = 1; for (int i = 0; i < 64; i++) { NSLog(@"processing group %i - file %i ", group, index++); psheet = [ImageUtils addImageToImage:psheet withImage2:collage andRect:CGRectMake((IMAGE_WIDTH*(column-1)) + (COLUMN_WIDTH * column), (IMAGE_HEIGHT * (row-1)) + ROW_OFFSET, IMAGE_WIDTH, IMAGE_HEIGHT) withImageWidth:PAGE_WIDTH withImageHeight:PAGE_HEIGHT]; column++; if (column > 3) { column = 1; row++; } if (index == 15) { group++; index = 1; row = 1; column = 1; UIImage *editedImage = [ImageUtils resizeImage:psheet withWidth:PAGE_WIDTH * 2 withHeight:PAGE_HEIGHT * 2]; editedImage = nil; } } }
ImageUtils方法
+(UIImage *) addImageToImage:(UIImage *)sheet withImage2:(UIImage *)label andRect:(CGRect)cropRect withImageWidth:(int) width withImageHeight:(int) height { CGSize size = CGSizeMake(width,height); UIGraphicsBeginImageContext(size); CGPoint pointImg1 = CGPointMake(0,0); [sheet drawAtPoint:pointImg1]; CGPoint pointImg2 = cropRect.origin; [label drawAtPoint: pointImg2]; UIImage* result = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return result; } + (UIImage*)resizeImage:(UIImage*)image withWidth:(CGFloat)width withHeight:(CGFloat)height { CGSize newSize = CGSizeMake(width, height); CGFloat widthRatio = newSize.width/image.size.width; CGFloat heightRatio = newSize.height/image.size.height; if(widthRatio > heightRatio) { newSize=CGSizeMake(image.size.width*heightRatio,image.size.height*heightRatio); } else { newSize=CGSizeMake(image.size.width*widthRatio,image.size.height*widthRatio); } UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0); [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return newImage; }
也许你的图片没有被释放,但移动到自动释放池 。
许多程序创build自动发布的临时对象。 这些对象添加到程序的内存占用空间直到块结束。 在许多情况下,允许临时对象累积直到当前事件循环迭代结束,不会导致过多的开销; 但是,在某些情况下,您可能会创build大量临时对象,这些临时对象大大增加了内存占用量,并且希望更快地处理这些对象。 在后面这些情况下,您可以创build自己的自动释放池块。 在块的末尾,临时对象被释放,这通常导致它们的释放,从而减less了程序的内存占用
尝试用@autoreleasepool {}
将代码包装在循环中:
for (int i = 0; i < 64; i++) { @autoreleasepool { NSLog(@"processing group %i - file %i ", group, index++); psheet = [ImageUtils addImageToImage:psheet withImage2:collage andRect:CGRectMake((IMAGE_WIDTH*(column-1)) + (COLUMN_WIDTH * column), (IMAGE_HEIGHT * (row-1)) + ROW_OFFSET, IMAGE_WIDTH, IMAGE_HEIGHT) withImageWidth:PAGE_WIDTH withImageHeight:PAGE_HEIGHT]; column++; if (column > 3) { column = 1; row++; } if (index == 15) { group++; index = 1; row = 1; column = 1; UIImage *editedImage = [ImageUtils resizeImage:psheet withWidth:PAGE_WIDTH * 2 withHeight:PAGE_HEIGHT * 2]; editedImage = nil; } } }