If you are working with a large number of images in an iPhone application, read on, chances are I can save you some trouble when it comes to memory management. Let me provide some background information…
I’ve been working on an application which has images divided into several sub-directories:
In addition, for each set of thumnails there is also an image that is viewable fullscreen, this image can also be saved to the camera roll if the user opts to do so.
All told, there are more 12 images sets, with up to 70 images per set. In addition, I’ve integrated a coverflow viewer that allows users to view a series of thumnails images by swiping left/right. To give you an idea of the space allocated for the coverflow, each image has a texture allocated that consumes 256K. With 70 images, I’m pushing 17MB. That does not include allocating each UIImage resource (from a file) to be shown on the texture.
With all that going for me, when it came to loading images for backgrounds, creating views, data structures, etc, you can see why it was important to keep a tight reign on allocation/releasing of objects.
One concept that wasn’t apparent up front, and the primary reason for this post, is that your choice of how you allocate UIImage can make a significant impact on your memory usage. What follows is a typical line of code, found in many examples and applications, for allocating images:
UIImageView *wallpaper = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"/imageSet02/wallpaper/pic02.png"]];
The good news is, the iPhone will cache this image, so if you make this same request again, the image will be loaded from an internal cache versus loading from a resource. Bad news is, the iPhone will cache this image. In my application, this subtle caching of images for the coverflow as well as the fullscreen image preview, led to a significant problem, ultimately causing the application to crash.
Here’s another means to allocate an image and avoid the system caching:
UIImageView *wallpaper = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:@"/imageSet02/wallpaper/pic02.png"]];
So, with that long intro it really comes down to choosing between imageWithContentsOfFile and imageNamed, depending on your whether or not you prefer to have images cached. Now mind you, all of this is documented in the API, which is the segue to the second reason for this post – read the documentation closely! Finally, if you find a code example that looks to fit the bill for your application, again, consult the docs before simply copying/pasting.