【问题标题】:Memory Leak with ARCARC 的内存泄漏
【发布时间】:2012-09-14 10:31:33
【问题描述】:
+(void)setup {
    UIImage* spriteSheet = [UIImage imageNamed:@"mySpriteSheet.png"];
    CGRect rect;
    animation = [NSMutableArray arrayWithCapacity:numberOfFramesInSpriteSheet];
    int frameCount = 0;

    for (int row = 0; row < numberFrameRowsInSpriteSheet; row++) {
        for (int col = 0; col < numberFrameColsInSpriteSheet; col++) {
            frameCount++;
            if (frameCount <= numberOfFramesInSpriteSheet) {
                rect = CGRectMake(col*frameHeight, row*frameWidth, frameHeight, frameWidth);
                [animation addObject:[UIImage imageWithCGImage:CGImageCreateWithImageInRect(spriteSheet.CGImage, rect)] ];
            }
         }
    }
}

在启用 ARC 的情况下编译上述代码。分析工具报告可能存在内存泄漏,因为 imageWithCGImage:: 返回 UIImage 计数 +1,然后引用丢失。 Leaks Instrument 报告根本没有内存泄漏。这里发生了什么?

此外,由于 ARC 禁止使用手动使用 release 等,如何修复泄漏?

感谢任何可以提供任何建议的人。

【问题讨论】:

    标签: objective-c ios memory memory-leaks automatic-ref-counting


    【解决方案1】:

    ARC 不管理 C 类型,其中可以考虑 CGImage。完成CGImageRelease(image);后必须手动释放引用

    +(void)setup {
        UIImage* spriteSheet = [UIImage imageNamed:@"mySpriteSheet.png"];
        CGRect rect;
        animation = [NSMutableArray arrayWithCapacity:numberOfFramesInSpriteSheet];
        int frameCount = 0;
    
        for (int row = 0; row < numberFrameRowsInSpriteSheet; row++) {
            for (int col = 0; col < numberFrameColsInSpriteSheet; col++) {
                frameCount++;
                if (frameCount <= numberOfFramesInSpriteSheet) {
                    rect = CGRectMake(col*frameHeight, row*frameWidth, frameHeight, frameWidth);
                    //store our image ref so we can release it later
                    //The create rule says that any C-interface method with "create" in it's name 
                    //returns a +1 foundation object, which we must release manually.
                    CGImageRef image = CGImageCreateWithImageInRect(spriteSheet.CGImage, rect)
                    //Create a UIImage from our ref.  It is now owned by UIImage, so we may discard it.
                    [animation addObject:[UIImage imageWithCGImage:image]];
                    //Discard the ref.  
                    CGImageRelease(image);
                }
             }
        }
    }
    

    【讨论】:

    • 还可以在这里查看我的问题的公认答案:stackoverflow.com/questions/6260256/…
    • “create 规则说,任何名称中带有“create”的 C 接口方法都会返回一个 +1 基础对象,我们必须手动释放它。” - 哦!当然。感谢科达菲!赞赏!
    • @Z.O.没问题。 create 规则实际上在文档中有点难以找到,但在处理 Apple 的 C-Interfaces 时它非常重要。 Here it is(连同 get 规则)。
    • @nielsbot 如果我们了解技术,那么以 CG 为前缀的结构不是 Core Foundation 的一部分,因此我将它们称为基础类型,与文档所称的一致。不过,它们遵循完全相同的规则,因此这些术语可以互换。
    • 如果文档称它们为基础类型,我想我们应该使用它。可惜我们也有 Foundation。
    【解决方案2】:

    核心基础数据结构均未处理 ARC。很多时候,这会产生问题。在这种情况下,我们必须手动释放内存。

    【讨论】:

      猜你喜欢
      • 2012-04-03
      • 2012-10-05
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      • 2013-08-19
      • 2014-04-03
      • 1970-01-01
      • 2011-10-23
      相关资源
      最近更新 更多