Xcode UIImage imageWithCGImage泄漏内存

时间:2019-06-08 03:30:59

标签: memory-leaks core-graphics

我在我的应用程序中启用了ARC,并注意到如果创建大量图像,我的应用程序将崩溃。作为调查的一部分,我创建了一个小项目,再现了here处的问题。示例项目代码的内容如下:

int width = 10;
int height = 10;
uint8_t data[100];

while (true)
{
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray();
    CGContextRef context = CGBitmapContextCreate(data, width, height, 8, width, colorspace, kCGBitmapByteOrderDefault | kCGImageAlphaNone);
    CGImageRef cgimage = CGBitmapContextCreateImage(context);

    // Remove this line and memory is stable, keep it and you lose 15-20 MB per second. Why?
    UIImage* uiimage = [UIImage imageWithCGImage:cgimage];

    CGImageRelease(cgimage);
    CGContextRelease(context);
    CGColorSpaceRelease(colorspace);
}

运行此代码时,Xcode的侧边栏将显示应用程序的总内存以每秒15-20 MB的速度增加。如果您注释掉创建UIImage的行,则泄漏将消失。

关于Stack Overflow的问题很多,关于在通过CGImage创建UIImage之后是否应该释放imageWithCGImage的问题,似乎并没有达成共识。但是,如果我不打CGImageRelease(cgimage),则每秒的内存使用量会增加100 MB以上,因此,我确定手动释放映像是正确的做法。

由于我已启用ARC,因此我在释放所有内容后尝试将uiimage设置为nil,但没有成功。不存储对imageWithCGImage:的调用的返回值也不能防止泄漏。

在使用Core Graphics方面我是否缺少一些基本知识?

1 个答案:

答案 0 :(得分:1)

  

在使用Core Graphics方面我是否缺少一些基本知识?

您似乎很可能缺少有关内存管理的一些基本知识。

许多Foundation / Cocoa框架命令,尤其是那些创建现成对象的命令,都会使它们成为自动发布的对象。这意味着您不必释放对象,因为使用完该对象后,它会自动释放。但是那怎么可能呢?这些对象进入自动释放池,一旦它们的保留计数下降到零,它们就会在有机会的时候被耗尽。但是您在不断循环,因此没有这样的机会。因此,您需要将麻烦的行包装在@autoreleasepool{}块中,以构造和消耗自己的池。

还请注意,可能存在您不知道的中间自动释放对象。自动释放池也可以为您提供帮助。

有关自动释放对象的更多信息,请参见this section of my book