代码之家  ›  专栏  ›  技术社区  ›  Adam Evans

xcode uiimage imagewithcgimage内存泄漏

  •  0
  • Adam Evans  · 技术社区  · 7 年前

    我在我的应用程序中启用了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 ,泄漏消失。

    关于是否应该释放 CGImage 创建uiimage后,通过 imageWithCGImage ,看起来并没有达成真正的共识。但是,如果我不打电话 CGImageRelease(cgimage) ,则内存使用量每秒增加100 MB以上,因此我确信手动释放映像是正确的做法。

    因为我启用了ARC,所以我试着设置 uiimage nil 在释放所有不起作用的东西之后。不存储对的调用的返回值 imageWithCGImage: 也不能防止泄漏。

    关于如何使用核心图形,我有没有遗漏一些基本的东西?

    1 回复  |  直到 7 年前
        1
  •  1
  •   matt    7 年前

    关于如何使用核心图形,我有没有遗漏一些基本的东西?

    似乎更可能是你遗漏了一些关于内存管理的基本知识。

    许多foundation/cocoa框架命令,特别是那些创建现成对象的命令,会生成 自动释放 是的。这意味着您不必释放该对象,因为它将在稍后自动释放,当您完成它时。但这怎么可能呢?这些物体进入 自动释放池 而且,一旦它们的保留数降到零,它们就会在以后有机会的时候被耗尽。但是你一直在循环,所以没有这样的机会。所以你需要用一个 @autoreleasepool{} 堵塞以便建造和排放自己的游泳池。

    还需要注意的是,可能有一些中间的自动释放对象,而您并不知道这些对象。自动释放池也可以帮助解决这些问题。

    this section of my book 有关自动释放对象的详细信息。