2010-03-04 87 views
7

我使用仪器来查看内存泄漏。至少在一个场景中,我经常滑动幻灯片/页面(在UIScrollView内),我没有看到任何内存泄漏。使用仪器 - 在“分配寿命”下,我切换到查看“Created & Still Living”并在整个过程中看到大约1.17MB的记忆。我认为这意味着我的应用程序只使用这么多的实际内存,其余部分正在被正确回收。内存警告和崩溃:如何处理

然而,在弹过100页左右的页面之后,我收到一条内存警告,然后我的一些视图被卸载,导致整个应用程序崩溃。

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

+0

没有线索依然。也许'仪器'不能正确地报告我可能有的泄漏。是否有其他内存泄漏查找工具更可靠? – climbon 2010-03-05 15:34:49

回答

11

The documentation says:

如果匹配的图像对象是不是已经在高速缓存中,这种方法加载从指定的文件中的图像数据,高速缓存,然后返回生成的对象。

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

仪器不会将此显示为泄漏,因为严格来说,它不是一个:某些(UIImage)仍然知道这些图像。泄漏仪器只会显示存在但不知道的物体的泄漏。不过,你仍然可以在乐器中看到这一点。

  1. 在跟踪文档中选择ObjectAlloc工具,并按当前计数或当前总大小对类列表进行排序。您会看到大部分内存被UIImage对象占用。
  2. 如果将鼠标悬停在UIImage行的class-name列上,您会看到一个go(转到iTunes Store)图标;如果你点击它,你会看到你的所有UIImage实例的列表。
  3. 然后,如果将鼠标悬停在实例行的地址列上,您将看到相同的按钮;这一次,点击它会将您带到该地址的历史记录,包括该地址所有对象的创建,保留,发布和释放。在这里,您可以看到图像的分配(在UIImage类中,由您排序几个堆栈帧),保留(由您)和发布(由您)。你也可以看到它还没有被UIImage释放--缓存仍然拥有图像,因此“泄漏”。

如果你不希望图像堆放这样,自己使用imageWithContentsOfFile:the -[NSBundle pathForResource:ofType:] method加载它们。我已经读过,自从iOS 3以来,UIImage将会在至少一些内存不足的情况下清除它的缓存,所以这不应该像以前那样是一个“泄漏”。你可能仍然会看到记忆堆积,但最终你会看到堆积物崩塌。如果你仍然看到内存堆积并且可以证明这是苹果的错,你应该记录你的证据和file a bug

+0

百万倍感谢! – RanLearns 2011-01-04 18:37:40

0

发现问题的根源。这是在下面的代码片段

UIImage *image = [UIImage imageNamed:imageFile]; 

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

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

我有图像的100S加上每个页面上的一些文字和用户可以通过他们的手指轻弹(就像他们在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强制释放内存?

+0

它正在自动释放。它也被其他东西所拥有。您可以通过查看Instruments中的单个UIImage实例来查看。 – 2010-03-06 22:23:12

2

您是否已将NSZombieEnabled环境变量设置为yes?它会导致释放对象留在内存中,因此不会让你重新获得内存。因此,如果激活,请尝试禁用它。

1

您是否检查过发布所有IBOutlet对象? 在你的dealloc上,你应该释放你拥有的任何IBOutlet对象,即使它们没有合成方法。

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

Check this answer in Stack Overflow

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];