gpt4 book ai didi

iphone - 图像创建函数中的内存泄漏

转载 作者:行者123 更新时间:2023-12-03 21:14:06 25 4
gpt4 key购买 nike

我目前正在开发一款 iPhone 游戏,需要即时创建一些动画。动画基于多个图像,由于图像组合的范围太大并且不可能预先创建所有序列,因此我希望能够在每次情况发生变化时重新计算一组图像。

该函数创建一系列图像,用作动画序列。我需要两件事的帮助:

  1. 我无法找到几个较大的内存泄漏 - 我需要帮助来定位它们
  2. 由于我是iPhone新手,我想知道是否有更好的方法,如果您对如何编写有更好的建议,请分享...

代码:

(void) updateImages:(int) smallPicID
{
CGRect smallPicRect;
smallPicRect.size = CGSizeMake(25.0f, 25.0f);

//TODO: add smallPic location for every image. Currently the values only match the first image...
static const CGPoint smallPicLocation[11][SMALLPIC_LOCATION_COUNT] =
{
{ {126.0f, 153.0f},{105.0f, 176.0f}, {115.0f, 205.0f}, {145.0f, 211.0f}, {166.0f, 188.0f}, {156.0f, 159.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} },
{ {183.0f, 91.0f}, {201.0f, 97.0f}, {205.0f, 115.0f}, {191.0f, 127.0f}, {173.0f, 122.0f}, {169.0f, 124.0f} }
};

for(int i = 0; i < self.m_finalImages.count; ++i)
{
// start with base image
UIImage * baseImg = [self.m_finalImagesEmpty objectAtIndex:i];
CGImageRef baseImgCtx = baseImg.CGImage;

// Create the bitmap context that matches the baseImg parameters
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef newImgCtx = CGBitmapContextCreate(NULL,
CGImageGetWidth(baseImgCtx),
CGImageGetHeight(baseImgCtx),
8, 0, colorSpace,
(kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
CGColorSpaceRelease(colorSpace);

if (newImgCtx == NULL)
{
// error creating context
assert(0);
return;
}

// Get empty drum image width, height.
size_t w = CGImageGetWidth(baseImgCtx);
size_t h = CGImageGetHeight(baseImgCtx);
CGRect rect = {{0,0},{w,h}};

// Draw the image to the bitmap context.
// newImgCtx now contains the full empty drum image.
CGContextDrawImage(newImgCtx, rect, baseImgCtx);

CGContextSaveGState(newImgCtx);
// translate & scale because of origin difference between UIKit and CG
CGContextTranslateCTM(newImgCtx, 0, h);
CGContextScaleCTM(newImgCtx, 1, -1);

int startLocation = 0;
int endLocation = SMALLPIC_LOCATION_COUNT;

// for each location
for(int j = startLocation; j < endLocation; j++)
{
// if its empty, nothing to do, move to next bullet
if (m_locationStatus[j] == CY_EMPTY)
continue;

UIImage * srcImg;
switch (m_locationStatus[j])
{
case CY_FULL: srcImg = [self.m_finalImagesLoaded objectAtIndex:i]; break;
case CY_USED: srcImg = [self.m_finalImagesSpent objectAtIndex:i]; break;
}

// create small image containing only the smallpic from the src img
smallPicRect.origin = smallPicLocation[i][j];
CGImageRef smallpicCGImg = CGImageCreateWithImageInRect(srcImg.CGImage, smallPicRect);

// draw the smallpic into the new context
CGContextDrawImage(newImgCtx, smallPicRect, smallpicCGImg);

CGImageRelease(smallpicCGImg);
}

CGContextRestoreGState(newImgCtx);

// update the image from the context
UIImage *baseImg = [self.m_finalImages objectAtIndex:i];
CGImageRef imgref = CGBitmapContextCreateImage(newImgCtx);
//[baseImg release];
[baseImg initWithCGImage:imgref];

CGContextRelease(newImgCtx);
}
}

最佳答案

首先引起我注意的是在接近尾部时使用 CGBitmapContextCreateImage() 创建 imgref,但没有匹配的 CGImageRelease(),以及 baseImg initWithCGImage: 消息除了消耗内存之外什么也不做。我认为您想将以“从上下文更新图像”开头的部分替换为以下内容:

CGImageRef imgref = CGBitmapContextCreateImage(newImgCtx);
UIImage *replacmentBaseImg = [[UIImage alloc] initWithCGImage:imgref];
CGImageRelease(imgref);

[self.m_finalImages replaceObjectAtIndex:i withObject:replacementBaseImg];
[replacementBaseImg release];

CGContextRelease(newImgCtx);

这假设 m_finalImages 是一个 NSMutableArray 并且您已经正确释放了已插入该数组中的其他图像,以便当您替换它们时它们会被释放。

在更大的结构说明中,您可能希望考虑将较小的子图像绘制到单独的 CALayers 中,然后将这些图层在屏幕的不同位置进出,以完成动画。 Quartz 绘图的成本很高,而 CALayers 是作为纹理存储在 GPU 上的缓存图像。其他人已经使用 CALayers 执行了这些基于 Sprite 的动画,并取得了令人印象深刻的性能。

关于iphone - 图像创建函数中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/891886/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com