内存警告和崩溃:如何处理它

时间:2010-03-04 08:48:57

标签: iphone cocoa-touch memory-leaks

我用仪器来查看内存泄漏。至少在我不断浏览幻灯片/页面的一个场景中(在UIScrollView中)我没有看到任何内存泄漏。使用乐器 - 在“Allocation lifespan”下,我切换到“Created& Still Living”,并看到整个内存大约1.17MB。我认为这意味着我的应用程序只使用了这么多的实际内存,并且正在正常回收其余部分。

然而,在浏览了100个左右的页面后,我收到了内存警告,然后我的几个视图被卸载,导致整个应用程序崩溃。

如果我没有使用大量内存并且没有内存泄漏,为什么我会收到内存警告?由于没有什么我可以真正释放,我没有看到避免崩溃的方法。任何人都遇到过这种情况或知道我该怎么办?我是否误解了乐器的任何内容?非常感谢任何评论。

5 个答案:

答案 0 :(得分:11)

The documentation says:

  

如果匹配的图像对象不在缓存中,则此方法从指定的文件加载图像数据,对其进行缓存,然后返回生成的对象。

因此,使用imageNamed:加载的每个图像在您释放其最后一个所有权后将继续存在于缓存中。

仪器没有将其显示为泄漏,因为严格来说,它不是一个:Something(UIImage)仍然知道这些图像。 Leaks仪器只会显示存在的物体的泄漏,但没有人知道。

但你仍然可以在乐器中看到这一点。

  1. 在跟踪文档中选择ObjectAlloc工具,并按当前计数或当前总大小对类列表进行排序。您将看到大部分内存被UIImage对象占用。
  2. 如果将鼠标悬停在UIImage行的类名列上,您将看到一个➲(转到iTunes商店)图标;如果单击它,您将看到所有UIImage实例的列表。
  3. 然后,如果将鼠标悬停在实例行的地址列上,您将看到相同的按钮;这一次,单击它将带您到该地址的历史记录,包括具有该地址的对象的所有创建,保留,发布和解除分配。

    在这里,您可以看到图像的分配(在UIImage类中,由您排序几个堆栈帧),保留(由您)和释放(由您)。您还可以看到它尚未被UIImage释放 - +[UIImage imageNamed:]缓存仍然拥有该图像,因此“泄漏”。

  4. 如果您不希望图片堆积如此,请使用imageWithContentsOfFile:the -[NSBundle pathForResource:ofType:] method自行加载。

    更新:我已经读过,自iOS 3以来,UIImage将在(至少某些)低内存情况下清除缓存,所以这不应该像它一样“泄漏”以前是。你可能仍然会看到记忆堆积起来,但是你最终会看到堆积崩溃。如果您仍然看到内存堆积并且可以证明这是Apple的错,那么您应该记录您的证据并file a bug

答案 1 :(得分:2)

您是否将NSZombieEnabled环境变量设置为yes?它会导致释放的对象在内存中持久存在,从而无法重新获得内存。因此,如果处于活动状态,请尝试禁用它。

答案 2 :(得分:1)

你检查过你释放所有IBOutlet对象吗? 在你的dealloc上你应该释放你对象中的任何IBOutlet对象,即使它们没有合成方法。

我们遇到了类似的问题,我们解决了它释放所有IBOutlets的问题。

Check this answer in Stack Overflow

答案 3 :(得分:1)

如果您只有3页,我了解您正在重复使用某些项目。

如果没有剩下的代码,很难说出现了什么问题,但也许你应该在创建一个新的代码之前尝试发布它。

尝试这样的事情:

IImage *image = [UIImage imageNamed:imageFile];

if (cartoon!=nil)
    [cartoon release];

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)];

cartoon.image = image ;
cartoon.backgroundColor = [UIColor brownColor];

答案 4 :(得分:0)

找到问题的根源。它位于以下代码段

UIImage *image = [UIImage imageNamed:imageFile];

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)];

cartoon.image = image ;
cartoon.backgroundColor = [UIColor brownColor];

我有100张图片,每页还有一些文字,用户可以通过手指轻弹滚动它们(就像在iPhone的照片应用程序中一样)。我只在我的UIScrollView中创建3个页面并加载/卸载(并且还释放)我明确分配的所有内容。因此,当发布卡通时,我只是发布卡通UIImageView,而不是UIImage认为它会自动发布。

但似乎没有被自动发布。我的应用程序收到内存警告(我不采取任何操作)并且操作系统卸载我的视图导致崩溃。

当我注释掉两行(下面修改过的片段)时,问题就消失了。没有警告没有崩溃。

    //UIImage *image = [UIImage imageNamed:imageFile];

cartoon = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 40.0, 320, 280)];

//cartoon.image = image ;
cartoon.backgroundColor = [UIColor brownColor];

有谁知道如何解决此问题?当警告发生时,有没有办法强制UIImage发布内存?