即使延迟加载,带有图像的滚动视图仍然崩溃?

Posted

技术标签:

【中文标题】即使延迟加载,带有图像的滚动视图仍然崩溃?【英文标题】:Scrollview with images still crashes even lazy load? 【发布时间】:2011-02-18 01:39:33 【问题描述】:

我有一个滚动视图,里面有几张图片,每张大约 100KB。我通过创建 uiviewcontrollers 来保存它们,将它们添加到 uiscrollview。控制器存储在滚动视图中。当图像滚动出可见区域时,我从超级视图中删除它的视图并用一些字符串替换它。我觉得我做得很好。但是滚动几次后我仍然崩溃(甚至在相同的 5 张图像上来回滚动)。

我注意到每个控制器的 dealloc 在从滚动视图中移除时都会被调用,而不是它的 viewDidUnload。

感谢任何帮助。

【问题讨论】:

另外,有时会有一些选择器发送到释放对象的异常,这无疑是视图控制器。我强烈怀疑释放视图控制器可能会与 didMemoryReceiveWarning 然后 viewDidUnload 的事情发生冲突。 您缺乏远见和计划并不构成我们的紧迫性。 抱歉措辞。我现在快撞墙了。 我有点迷路了。我使用相同的应用程序框架来构建一个具有更多更大图像的应用程序。该应用程序运行良好。我需要做更多调查。 【参考方案1】:

viewDidUnloadviewController 本身释放它的视图时被调用。如果释放了视图,则调用(这意味着viewDidUnload 仅与内存警告情况相关)。为了完全删除视图及其视图控制器,您应该从其父视图中删除视图,然后释放视图控制器。然后正常viewDidUnload不被调用。

很难理解您是如何实现的,以及为什么会出错。但让我提出一些建议。

viewWillAppearviewDidAppearviewWillDisappearviewDidDisappear 等视图控制器的方法在这里没有用处,因为它们都不能告诉你视图当前是否在屏幕上。唯一可以判断的方法是在每次滚动发生时获取滚动视图的contentOffset(通过 UIScrollViewDelegate 的委托方法),然后检查这些视图是否位于可见区域。

因此,这里没有必要使用 UIViewController。只需使用视图,例如 UIImageView。当视图可见时动态创建视图实例,或者更理想的是,当它接近可见区域时。

【讨论】:

感谢您的回答。一开始我用的是UIImageView,后来改用uiviewcontroller,希望内存占用少一些。正如我自己回答的那样,我一定有其他问题。可能开始的视频没有尽快从内存中释放出来。 我强烈建议使用 NSZombieEnabled 来找出您的应用程序崩溃的原因。如果是关于错误释放对象的问题,您可能很快就会找到它。 我已经使用过 NSZombieEnabled。该应用程序在模拟器上运行良好。我还使用工具来检查分配。但存活的对象从未超过 3MB。 我明白了。构建中有任何可能的问题吗?甚至没有一些看起来有用的日志或崩溃报告吗?我认为其他人需要更多信息才能弄清楚发生了什么。祝你好运。 谢谢。我会多花一点时间来挖掘。【参考方案2】:

我遇到了这个问题,现在解决了。希望它适用于其他人。 :) 下面是导致崩溃的代码示例(第 3 行):

UIImage *image = [image imageNamed:@"img.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[image release]; // Need not release here!!!
...
[cellView addSubview:imageView];
[imageView release];

【讨论】:

以上是关于即使延迟加载,带有图像的滚动视图仍然崩溃?的主要内容,如果未能解决你的问题,请参考以下文章

在 UIScrollView 中延迟加载不同尺寸的图像而不分页

UICollectionView 加载延迟并且滚动非常颠簸

具有延迟加载和下载图像的 ListView [重复]

延迟加载

React 延迟加载/无限滚动解决方案

使用从互联网下载的图像延迟加载 GridView