我有一种方法需要逐像素解析一堆大PNG图像(每个PNG为600x600像素)。它在Simulator上似乎工作得很好,但是在设备(iPad)上,我在某些内部存储器复制功能中得到了EXC_BAD_ACCESS。大小似乎是罪魁祸首,因为如果我在较小的图像上尝试,一切似乎都可以正常工作。这是下面与方法有关的内存。

+ (CGRect) getAlphaBoundsForUImage: (UIImage*) image
{
    CGImageRef imageRef = [image CGImage];

NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

unsigned char *rawData = malloc(height * width * 4);
memset(rawData,0,height * width * 4);

NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);

/* non-memory related stuff */

free(rawData);

当我在一堆图像上运行它时,它会运行12次,然后爬出,而在模拟器上,它却没有问题。你们有什么主意吗?

最佳答案

运行12次然后崩溃听起来像是内存不足的问题。可能是CGContext在内部正在创建一些大型的自动发布结构。由于您是在循环执行此操作,因此它们不会被释放,因此您的内存用完了就死​​了。

我不确定Core Foundation如何处理临时对象。我不认为CF对象具有自动释放的功能,Core Graphics上下文几乎可以肯定是处理CF对象而不是NSObject。

为了减少代码中的内存流失,建议您在开始处理之前将其重构为创建一个屏幕外的CGContext,然后重复使用它来处理每个图像。完成后再将其释放。在任何情况下,这都会更快(因为您不会在循环的每次通过中分配巨大的数据结构。)

我敢打赌,这将消除您的崩溃问题,而且我敢打赌,它还可以使您的代码快得多。与其他操作相比,内存分配的速度非常慢,并且您正在围绕一些相当大的数据结构进行处理以处理600x600像素RGBA图像。

关于iphone - 在iPhone/iPad上的CGBitmapContextCreate,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2619224/

10-09 03:34