如果你在你的iPhone应用程序中使用了大量的图像,请继续读下去,我有可能将你从内存管理的泥潭中解救出来。首先我们提供一些背景信息……
我工作的应用程序的图像分配在许多子目录下:
/imageSet01/thumbnails/pic01.png
/imageSet01/thumbnails/pic02.png
…
/imageSet10/thumbnails/pic01.png
/imageSet10/thumbnails/pic02.png
另外,每套缩略图都有一张可见的全屏图像,如果用户愿意,每张图像还可以存储到照相机卷中。
/imageSet01/wallpaper/pic01.png
/imageSet01/wallpaper/pic02.png
…
/imageSet10/wallpaper/pic01.png
/imageSet10/wallpaper/pic02.png
总共有12套图像,每套可以有多达70张图像。另外,我还集成了一个coverflow浏览器,允许用户通过左右拖动来观看一系列缩略图像。下面了解一下coverflow的内存分配,每张图像都有一个占用256K的内存的纹理。70张图像将占用17MB空间。这还不包括为显示这些图像每个UIImage从文件分配的资源。
考虑到所有这些,当你为背景加载图像,创建视图,数据结构等等时,你就可以知道为什么小心为对象分配/释放内存是多么重要了。
前面没有提到的一个概念,也就是这篇文章的主要议题,是选择怎样分配UIImage将对内存的使用产生重大的影响。下面的几行代码是为图像分配内存的的典型代码,你可以在许多示例和应用程序中看到:
1 2 | UIImageView *wallpaper = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"/imageSet02/wallpaper/pic02.png"]]; |
好消息是iPhone将为这个图像提供缓存,所以如果你再次需要同一图像时,图像将被从内部缓存而不是从资源中加载。而坏消息也是iPhone将为此图像提供缓存。在我的程序中,为coverflow中图像以及全屏图像预览提供的少量缓存,将产生很大的问题,以致最后导致程序崩溃。
下面是另一种为图像分配内存的方法并可以避免系统缓存:
1 2 | UIImageView *wallpaper = [[UIImageView alloc] initWithImage: [UIImage imageWithContentsOfFile:@"/imageSet02/wallpaper/pic02.png"]]; |
我花了这么长篇幅的介绍,实际上归结于在imageWithContentsOfFile和imageNamed之间的取舍,它取决于你是否希望图像被缓存。所有这些在API文档中都有提到,这是这篇文章的第二个目的 – 仔细地阅读文档!最后,如果你找到了一段看上去适合你的程序时,再次记住在简单拷贝/粘帖前,一定要读一下文档。



