2

I'm developing an app which uses a UIScrollView to show a list of images based on search criteria. Using a button the user can load more images.

When testing on an iPhone 4 the ViewController receives a memory-warning at ~750 images. When testing on an iPod 2nd generation a memory warning is received at ~150 images.

My understanding is that when didReceiveMemoryWarning is called, one can free memory by releasing objects but recovery from low memory is not guaranteed.

I've implemented didReceiveMemoryWarning and release basically all objects. In instruments I see memory usage drop back to ~3MB. The first time the iPod reaches its memory limit all goes well, memory is released and the app resumes normal operation. The second time however, when didReceiveMemoryWarning is called, I can see the objects released, but the app crashes anyway.

So, how do I make my app crash proof? I want to make sure that all devices running the app can load as much images as memory allows but I also want to make sure that the app doesn't crash.

I would prefer the app never to reach didReceiveMemoryWarning and set a limit to the number of images that can be displayed, but how can I determine how many images each possible device should be able to load?

Furthermore, the size of the images is not guaranteed. While testing I come to this arbitrary number of 150 on an iPod, but what if the images on the server at some point in time are twice as big? Then the app would probably crash at 75 images.

Any sugestions?

4

2 回答 2

1

首先,您可能想要做的不是一次显示所有图像。您可能只想禁用当前可见的图像,以及一些在用户滚动到该位置时预加载的屏幕外图像。

这与照片应用程序的工作方式非常相似,如何UITableView实现。基本上可以归结为:

你有你的主滚动视图,在它里面,你有单独的单元格。这些单元格是作为子视图添加到特定偏移量的滚动视图的小视图。然后,您将图像添加到这些单元格中。

当用户滚动滚动视图时,您首先要求滚动视图为您出列一个新单元格,这与您要求表格视图出列一个单元格供您使用的方式非常相似。如果已回收,这将节省分配成本。如果你不能从回收的集合中取出一个,那么你要做的很简单:按照你目前的做法分配一个。

此外,要实现此单元格回收,您需要做的是查看哪些单元格在屏幕上可见。如果一个或多个单元格离开屏幕,则将它们添加到NSSet您创建的回收单元格中。这套只是保存细胞供以后回收利用。Apple 提供了一些示例代码来演示这一点,它被称为PhotoScroller。它也在 WWDC10 视频第 104 节中进行了演示。我建议您观看它。忽略关于平铺的部分,你不需要知道你的目的。

一旦你有了这个,这将迫使你只在需要时设置你的单元格,这也是这种行为的另一个关键方面。

最后,当您收到内存警告时,只需删除回收的单元集。如果你变得足够高,这很重要,也就是说,你将节省几兆内存。:) (不要忘记实现它,但是,当您持有您并不特别需要的临时数据时......屏幕上不可见的单元格就是一个很好的例子,缓存也是如此。)

于 2010-11-25T14:36:31.497 回答
0

您应该延迟加载图像并仅加载当时需要的图像。无论如何,您的应用程序无法在一个屏幕上显示所有这些图像,因此在您的滚动视图上,您​​应该只加载那些可以适合屏幕的图像,并且可能只加载一些图像,并且当用户滚动以释放不再需要的图像时.

于 2010-11-25T14:35:41.450 回答