1

我的应用程序发生了奇怪的崩溃,没有任何痕迹。这可能是与内存相关的问题,但信息很少,我不确定如何继续或修复它。如果不是因为乐器,就永远不知道是什么了。

我有一个图像数组(在此示例中为大小为 2 的数组),我在其中加载图像,创建图像上下文并绘制并将其保存到数组中。每次调用该方法时,图像数组对象都会被新内容替换。在仪器中,我在此方法调用期间看到非常巨大的虚拟内存使用量,显然在每次调用内存未清除后,因此崩溃。该项目是ARC。我将在下面列出代码。这就是我们重新创建此问题所需的全部内容。(我使用的图像大小约为 7MB,因此更容易重新创建崩溃)。我也在使用 iPad2 设备。

+ (UIImage *)imageCopy:(UIImage *)src
{
    UIGraphicsBeginImageContext(src.size);
    [src drawAtPoint:CGPointZero];
    UIImage *r = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return r;
} 

- (IBAction)buttonTouch:(id)sender
{
    for (int i=0; i<2; i++)
    {
        if (i==0)
        {
            self.mImage = [UIImage imageNamed:@"LARGE_elevation.jpg"];
        }
        else
        {
            self.mImage = [UIImage imageNamed:@"LARGE_elevation2.jpg"];
        }
        // imageArray is a NSMutableArray with capacity of 2
        [imageArray setObject:[ViewController imageCopy:self.mImage] atIndexedSubscript:i];
    }
    ((UIImageView *)[self.view viewWithTag:100]).image = self.mImage;
}

这是仪器的屏幕,在发出内存警告后第二次崩溃。

仪器截图

我在这里使用的“imageCopy”方法没有看到任何大问题。

对此的任何帮助都非常感谢。谢谢和干杯,

4

2 回答 2

1

我发现这是一个循环引用问题。因此,当新内容替换数组中的旧内容时,过去的对象仍然存在。这是一个非常有趣的发现,因为在内存泄漏分析器中它显示的数据泄漏只有几 KB,您不会怀疑这是因为未释放的虚拟内存只有几百兆字节 (MB)。

作为一个非常抽象的例子。

ClassA

@property (strong) ClassB *obj

----------

ClassB

@property (strong) ClassA *obj

- (id)initWithA:(ClassA *)objA;
----------

因此,当您删除 A 时,两个对象都不会被正确释放。在我的情况下,泄漏分析器跟踪的泄漏对于两个对象来说都是几 KB,即使 CoreGraphics 计算挂在虚拟内存中大约 200MB 的数据上。

修复是将 ClassB 中的 A 引用标记为弱。

ClassB

@property (weak) ClassA *obj

- (id)initWithA:(ClassA *)objA;

判决

  • 永远不要低估内存泄漏,无论大小 & arc 或 mrc
于 2013-06-20T07:57:50.930 回答
0

The problem is probably that the method imageNamed: caches the images loaded, and there is apparently no way to clear the cache after a memory warning programmatically.
Instead of imageNamed:, you could use other methods like initWithData: that do not cache the images. You will find a detailed discussion here.

于 2013-05-29T05:20:34.103 回答