Alexander
Alexander

Reputation: 419

How to manage memory on iPhone when handling many images

I have kind of a unique problem in the project I'm working in. What I'm doing is creating sort of a "wall" of scrollable images that are downloaded from a server that our user can flick through on the iPhone. But the problem is we're having trouble coming up with a good memory management plan here. What we have running right now is a class that subclasses UIImageView that is being used to store every image we download from the server (these images are saved to the app's documents directory though), and then we also add meta data to it (i.e. description, tags, etc). We are then storing this in an NSMutableArray that we then loop through with all the images to place them in our wall. As you would imagine having all these images in memory is an enormous memory hog. We are having a hard time thinking of a way to do this without using this much of memory. One of the bigger problems that makes it more difficult is that the images, when placed, need to report when being touched. So I don't think we can just deallocate them after placing them. Have any of you had experience with handling objects of any kind with large size like this and having to do have them at hand to draw to the screen, play, etc? What type of technique or approach do you suggest? I've read around about CoreData but don't know if this is what I'm looking for. Appreciate any help.

Here's the main drawing method for reference:

SOLUTION: WWDC Session Video #104!

Upvotes: 0

Views: 676

Answers (4)

Daniel Blezek
Daniel Blezek

Reputation: 4549

This has basically been solved for you by David Golighty. We've used the ImageCache code successfully for 600+ images without a hiccup. Because of the way the caching works, we easily flip through 300 512x512 PNG images on both the iPhone and iPad with high frames-per-second.

Upvotes: 1

David Liu
David Liu

Reputation: 9601

So really, what you need is a system of enqueuing and dequeuing views as they come and go.

An easy example you should be looking at is the Photos app that already exists on your iPhone. Although you might have a million images on your "wall", you can only see so many images at one time on your screen. That means you don't need a million UIImageViews for all of the images on the wall, just the 20 or so that fit onto the screen.

Think of the wall not as a single big view that's available all the time, but instead follow the paradigm laid out by UITableView. A UITableView enqueues UITableViewCells as they disappear and (hopefully) the datasource dequeues and reuses those table cells by just changing the information displayed to the one in the new row.

You shouldn't have any problems reporting touches on which image is touched (since you can just look at what image is contained in the imageview, or through some other saved property).

The above principles should also apply to the UIImages themselves; since you're saving them to disk, you don't necessarily need them all in memory, so think about releasing and getting them on demand. One thing to note: Sometimes scrolling can get pretty slow when you're reading images from disk, so it's a tradeoff you'll need to investigate for yourself.

Upvotes: 1

mvds
mvds

Reputation: 47034

As long as the images come from disk, and read in using one of the UIImage convenience methods, the UIImage will remain backed by the file, and release memory when needed. It will re-read the file when needed as well. This is all just in the UIImage docs btw.

ps. even when loading an image from the iPhone library, it remains backed by the file (which your app cannot touch). The low-res version needed for display is kept as well btw. You can clearly see this happening in Instruments. An open question of me is if this is if camera images are backed by a file as well.

Upvotes: 1

Lou Franco
Lou Franco

Reputation: 89152

For one, resample them down to a reasonable size -- presumably, you only need them to be about the screen's size or smaller. If you zoom in, go get the original for just that image.

Also, make a custom view (subclass of UIView) that draws the image (in drawRect) when it's visible and unloads the image when it's off-screen.

Upvotes: 0

Related Questions