Ios iPad应用程序在合并/合并两幅图像时因内存警告而崩溃
我的应用程序正在崩溃,因为我在进行图像处理时大量使用了内存 基本上,我的整个应用程序都依赖于下面的方法,其中使用了用于组合图像的逻辑,这是我用于从bundle加载图像的另一种方法Ios iPad应用程序在合并/合并两幅图像时因内存警告而崩溃,ios,memory-management,memory-leaks,uiimageview,uiimage,Ios,Memory Management,Memory Leaks,Uiimageview,Uiimage,我的应用程序正在崩溃,因为我在进行图像处理时大量使用了内存 基本上,我的整个应用程序都依赖于下面的方法,其中使用了用于组合图像的逻辑,这是我用于从bundle加载图像的另一种方法 + (UIImage*)imageByCombiningImages:(UIImage*)firstImage withImage:(UIImage*)secondImage { @autoreleasepool { UIImage *image = nil; CGSi
+ (UIImage*)imageByCombiningImages:(UIImage*)firstImage withImage:(UIImage*)secondImage
{
@autoreleasepool
{
UIImage *image = nil;
CGSize newImageSize = CGSizeMake(MAX(firstImage.size.width, secondImage.size.width), MAX(firstImage.size.height, secondImage.size.height));
if (UIGraphicsBeginImageContextWithOptions != NULL)
{
UIGraphicsBeginImageContextWithOptions(newImageSize, NO, [[UIScreen mainScreen] scale]);
}
else
{
UIGraphicsBeginImageContext(newImageSize);
}
[firstImage drawAtPoint:CGPointMake(roundf((newImageSize.width-firstImage.size.width)/2), roundf((newImageSize.height-firstImage.size.height)/2))];
firstImage =nil;
[secondImage drawAtPoint:CGPointMake(roundf((newImageSize.width-secondImage.size.width)/2), roundf((newImageSize.height-secondImage.size.height)/2))];
secondImage=nil;
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
}
- (UIImage*) getImage:(NSString*)imagename
{
NSString *fileName = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:imagename];
UIImage *image = [UIImage imageWithContentsOfFile:fileName];
return image;
}
下面的方法多次调用上述方法
- (void) applyMaterialWithValue:(NSDictionary*)dict
{
@synchronized(self)
{
NSString *materialName = [dict valueForKey:@"material"];
NSString *optionName = [dict valueForKey:@"option"];
//NSString *preset_Name = [dict valueForKey:@"preset"];
NSString *name = [dict valueForKey:@"name"];
if([[GlobalIntVariable getCMFScheme] isEqualToString:@"preset1"])
{
if(!isMetalPressed)
{
[GlobalIntVariable setCurrentMaterialName:@"Preset 1 Metal Plating"];
}
if(!isLeatherPressed)
{
[GlobalIntVariable setCurrentPresetName:@"preset1"];
}
}
if([[GlobalIntVariable getCMFScheme] isEqualToString:@"preset2"])
{
if(!isMetalPressed)
{
[GlobalIntVariable setCurrentMaterialName:@"Preset 2 Metal Plating"];
}
if(!isLeatherPressed)
{
[GlobalIntVariable setCurrentPresetName:@"preset2"];
}
}
if ([materialName isEqualToString:AREAD4METALCOMPONENET ]|| [materialName isEqualToString:AREA8METALCOMPONENET])
{
[GlobalIntVariable setCurrentMaterialName:name];
}
if([optionName isEqualToString:OPTION0])
{
@autoreleasepool
{
UIImage *presetImg1L1Standard = [APP_DEL getImage:[dict valueForKey:@"image1L1Standard"]];
imgView1Layout1Standard.image = [ImageOperations imageByCombiningImages:imgView1Layout1Standard.image withImage:presetImg1L1Standard];
imgView1Layout1StandardPSUOn.image = [ImageOperations imageByCombiningImages:imgView1Layout1StandardPSUOn.image withImage:presetImg1L1Standard];
presetImg1L1Standard=nil;
UIImage *presetImg1L1Premium = [APP_DEL getImage:[dict valueForKey:@"image1L1Premium"]];
imgView1Layout1Premium.image = [ImageOperations imageByCombiningImages:imgView1Layout1Premium.image withImage:presetImg1L1Premium];
imgView1Layout1PremiumPSUOn.image = [ImageOperations imageByCombiningImages:imgView1Layout1PremiumPSUOn.image withImage:presetImg1L1Premium];
presetImg1L1Premium=nil;
UIImage *presetImg1L2Standard = [APP_DEL getImage:[dict valueForKey:@"image1L2Standard"]];
imgView1Layout2Standard.image = [ImageOperations imageByCombiningImages:imgView1Layout2Standard.image withImage:presetImg1L2Standard];
imgView1Layout2StandardPSUOn.image = [ImageOperations imageByCombiningImages:imgView1Layout2StandardPSUOn.image withImage:presetImg1L2Standard];
presetImg1L2Standard=nil;
UIImage *presetImg1L2Premium = [APP_DEL getImage:[dict valueForKey:@"image1L2Premium"]];
imgView1Layout2Premium.image = [ImageOperations imageByCombiningImages:imgView1Layout2Premium.image withImage:presetImg1L2Premium];
imgView1Layout2PremiumPSUOn.image = [ImageOperations imageByCombiningImages:imgView1Layout2PremiumPSUOn.image withImage:presetImg1L2Premium];
presetImg1L2Premium=nil;
}
@autoreleasepool
{
UIImage *presetImg2L1Standard = [APP_DEL getImage:[dict valueForKey:@"image2L1Standard"]];
imgView2Layout1Standard.image = [ImageOperations imageByCombiningImages:imgView2Layout1Standard.image withImage:presetImg2L1Standard];
imgView2Layout1StandardPSUOn.image = [ImageOperations imageByCombiningImages:imgView2Layout1StandardPSUOn.image withImage:presetImg2L1Standard];
presetImg2L1Standard=nil;
UIImage *presetImg2L1Premium = [APP_DEL getImage:[dict valueForKey:@"image2L1Premium"]];
imgView2Layout1Premium.image = [ImageOperations imageByCombiningImages:imgView2Layout1Premium.image withImage:presetImg2L1Premium];
imgView2Layout1PremiumPSUOn.image = [ImageOperations imageByCombiningImages:imgView2Layout1PremiumPSUOn.image withImage:presetImg2L1Premium];
presetImg2L1Premium=nil;
UIImage *presetImg2L2Standard = [APP_DEL getImage:[dict valueForKey:@"image2L2Standard"]];
imgView2Layout2Standard.image = [ImageOperations imageByCombiningImages:imgView2Layout2Standard.image withImage:presetImg2L2Standard];
imgView2Layout2StandardPSUOn.image = [ImageOperations imageByCombiningImages:imgView2Layout2StandardPSUOn.image withImage:presetImg2L2Standard];
presetImg2L2Standard=nil;
UIImage *presetImg2L2Premium = [APP_DEL getImage:[dict valueForKey:@"image2L2Premium"]];
imgView2Layout2Premium.image = [ImageOperations imageByCombiningImages:imgView2Layout2Premium.image withImage:presetImg2L2Premium];
imgView2Layout2PremiumPSUOn.image = [ImageOperations imageByCombiningImages:imgView2Layout2PremiumPSUOn.image withImage:presetImg2L2Premium];
presetImg2L2Premium=nil;
}
@autoreleasepool
{
UIImage *presetImg3L1Standard = [APP_DEL getImage:[dict valueForKey:@"image3L1Standard"]];
imgView3Layout1Standard.image = [ImageOperations imageByCombiningImages:imgView3Layout1Standard.image withImage:presetImg3L1Standard];
imgView3Layout1StandardPSUOn.image = [ImageOperations imageByCombiningImages:imgView3Layout1StandardPSUOn.image withImage:presetImg3L1Standard];
presetImg3L1Standard=nil;
UIImage *presetImg3L1Premium = [APP_DEL getImage:[dict valueForKey:@"image3L1Premium"]];
imgView3Layout1Premium.image = [ImageOperations imageByCombiningImages:imgView3Layout1Premium.image withImage:presetImg3L1Premium];
imgView3Layout1PremiumPSUOn.image = [ImageOperations imageByCombiningImages:imgView3Layout1PremiumPSUOn.image withImage:presetImg3L1Premium];
presetImg3L1Premium=nil;
UIImage *presetImg3L2Standard = [APP_DEL getImage:[dict valueForKey:@"image3L2Standard"]];
imgView3Layout2Standard.image = [ImageOperations imageByCombiningImages:imgView3Layout2Standard.image withImage:presetImg3L2Standard];
imgView3Layout2StandardPSUOn.image = [ImageOperations imageByCombiningImages:imgView3Layout2StandardPSUOn.image withImage:presetImg3L2Standard];
presetImg3L2Standard=nil;
UIImage *presetImg3L2Premium = [APP_DEL getImage:[dict valueForKey:@"image3L2Premium"]];
imgView3Layout2Premium.image = [ImageOperations imageByCombiningImages:imgView3Layout2Premium.image withImage:presetImg3L2Premium];
imgView3Layout2PremiumPSUOn.image = [ImageOperations imageByCombiningImages:imgView3Layout2PremiumPSUOn.image withImage:presetImg3L2Premium];
presetImg3L2Premium=nil;
}
}
@autoreleasepool
{
UIImage *presetImg4Standard = [APP_DEL getImage:[dict valueForKey:@"image4Standard"]];
mainImageView4.image=[ImageOperations imageByCombiningImages:mainImageView4.image withImage:presetImg4Standard];
presetImg4Standard=nil;
UIImage *presetImg5Standard = [APP_DEL getImage:[dict valueForKey:@"image5Standard"]];
mainImageView5.image=[ImageOperations imageByCombiningImages:mainImageView5.image withImage:presetImg5Standard];
presetImg5Standard=nil;
}
@autoreleasepool
{
UIImage *presetImg1Detail1 = [APP_DEL getImage:[dict valueForKey:@"image1DetailView1"]];
imgView1Detail.image = [ImageOperations imageByCombiningImages:imgView1Detail.image withImage:presetImg1Detail1];
presetImg1Detail1=nil;
UIImage *presetImg2Detail2 = [APP_DEL getImage:[dict valueForKey:@"image2DetailView2"]];
imgView2Detail.image = [ImageOperations imageByCombiningImages:imgView2Detail.image withImage:presetImg2Detail2];
presetImg2Detail2=nil;
UIImage *presetImg3Detail3 = [APP_DEL getImage:[dict valueForKey:@"image3DetailView3"]];
imgView3Detail.image = [ImageOperations imageByCombiningImages:imgView3Detail.image withImage:presetImg3Detail3];
presetImg3Detail3=nil;
}
[self setMaterialReflection];
NSString *strShowIndicator = [dict valueForKey:@"hideIndicator"];
if ([strShowIndicator isEqualToString:@"YES"]) {
[appDelegate hideIndicator];
}
}
}
问题是,当上述方法调用的内存使用量超过400 mb时,我在控制台中收到2-3倍的内存警告消息,我的应用程序在此之后崩溃
在运行时,当执行上述方法时,内存总是在增加,即使您在上述方法中看到,我也没有所有uiimage对象&也使用@autorelese块,但内存没有释放
我想在每次调用以下方法后减少内存
- (UIImage*)图像通过组合图像:(UIImage*)第一个图像与图像:(UIImage*)第二个图像
请建议我如何改进图像合成方法如何优化上述方法?这样可以减少内存使用量,我的应用程序可以顺利运行。我可以建议不要每次都从图形上下文中绘制图像 请尝试以下步骤:
+ (UIImage*)imageByCombiningImages:(NSDictionary *)imageDict
{
UIImage *image = nil;
CGSize newImageSize = CGSizeZero;
NSArray *allImages = [imageDict allValues];
for (UIImage *image in allImages) {
newImageSize = CGSizeMake(MAX(image.size.width, newImageSize.size.width), MAX(image.size.height, newImageSize.size.height));
}
if (UIGraphicsBeginImageContextWithOptions != NULL)
{
UIGraphicsBeginImageContextWithOptions(newImageSize, NO, [[UIScreen mainScreen] scale]);
}
else
{
UIGraphicsBeginImageContext(newImageSize);
}
for (UIImage *image in allImages) {
[image drawAtPoint:CGPointMake(roundf((newImageSize.width-image.size.width)/2), roundf((newImageSize.height-image.size.height)/2))];
}
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
编辑2:
使用UIGraphicsGetImageFromCurrentImageContext()创建图像时,核心图形将创建内部cg光栅数据以创建位图图像。它将消耗更多内存
通过延迟顺序方法调用以合并映像,可以避免内存警告
编辑3:
修改的图像合并方法:
- (void)imageByCombiningImages:(UIImage*)firstImage withImage:(UIImage*)secondImage
{
UIImage *image = nil;
CGSize newImageSize = CGSizeMake(MAX(firstImage.size.width, secondImage.size.width), MAX(firstImage.size.height, secondImage.size.height));
if (UIGraphicsBeginImageContextWithOptions != NULL)
{
UIGraphicsBeginImageContextWithOptions(newImageSize, NO, [[UIScreen mainScreen] scale]);
}
else
{
UIGraphicsBeginImageContext(newImageSize);
}
[firstImage drawAtPoint:CGPointMake(roundf((newImageSize.width-firstImage.size.width)/2), roundf((newImageSize.height-firstImage.size.height)/2))];
firstImage =nil;
[secondImage drawAtPoint:CGPointMake(roundf((newImageSize.width-secondImage.size.width)/2), roundf((newImageSize.height-secondImage.size.height)/2))];
secondImage=nil;
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self performSelector:@selector(merge:) withObject:image afterDelay:1]; // modify the delay which will work out for you
}
在数组中添加所有图像键并调用该方法
- (void)merge:(UIImage *)image {
switch (rowIndex) {
case 0: {
UIImage *presetImg1L1Standard = [APP_DEL getImage:[dict valueForKey:[imagesArray objectAtIndex:rowIndex]]];
switch (sectionIndex) {
case 0:
[ImageOperations imageByCombiningImages:imgView1Layout1Standard.image withImage:presetImg1L1Standard];
sectionIndex++;
break;
case 1:
imgView1Layout1Standard.image = image;
[ImageOperations imageByCombiningImages:imgView1Layout1StandardPSUOn.image withImage:presetImg1L1Standard];
rowIndex ++;
sectionIndex = 0;
break;
default:
break;
}
}
break;
case 1: {
UIImage *image = [APP_DEL getImage:[dict valueForKey:[imagesArray objectAtIndex:rowIndex]]];
switch (sectionIndex) {
case 0:
imgView1Layout1StandardPSUOn.image = image;
[ImageOperations imageByCombiningImages:imgView1Layout1Premium.image withImage:image];
sectionIndex++;
break;
case 1:
imgView1Layout1Premium.image = image;
[ImageOperations imageByCombiningImages:imgView1Layout1Premium.image withImage:presetImg1L1Premium];
rowIndex ++;
sectionIndex = 0;
break;
default:
break;
}
}
break;
// ................. and so on
default:
break;
}
}
希望这能给你一个想法。我会尝试在GPU上进行计算,例如使用一个的。谢谢你的建议…但我不明白你想说什么…你能通过组合Images:method编辑我的图像吗?这样我就可以在我的code@PRJ如果您需要有关编辑2方法的更多帮助,请随时联系。我将帮助您编写代码片段…但这是我最后一个解决方案,您能给出一些建议如何改进applyMaterialWithValue:method吗?您说过您有内存泄漏(参见标记),但到底是哪一行导致内存泄漏?仪器怎么说?图像的像素有多大?它们以2MB的大小存储(如JPEG、PNG?),并不意味着它们在内存中占用2MB的空间。。。