views:

139

answers:

1

So I've seen this question asked before and in fact I asked it last night but I thought I'd give it another go just to see if I could get any other unique views on the problem.

The Problem — I have an app with a large number of uiimageviews (with image downloaded to disk) in a scrollview which of course has two large problems facing it: Memory use, and performance. In my app memory use isn't so much a problem because I am employing techniques such as dequeuing and reusing imageviews and such. But performance is another thing entirely. Right now, as a memory saving procedure, I only store image filepaths in memory because it would be ridiculous to store images in memory. But the problem with this is that reading from the disk takes more time than from memory and slows down scrolling on the scrollview immensely.

So, what kind of techniques do any of you suggest for something like this? I've seen three20 but don't want to use it because I need high customizability in my view and that just won't do. Image files are not large, but just thumbnail size so there is no scaling or excess size. There's got to be an intuitive way to handle this. The built in photos app handles up to thousands of photos perfectly with low memory and slick and smooth scrolling performance.

+1  A: 

Fundamentally, the problem is that you're probably doing a bunch of disk I/O on your UI thread, which is basically guaranteed to cause performance problems.

You should consider loading your images on a background thread and updating the image views on the main thread when the images are loaded. Depending on your use case you can get more or less clever about how far you preload in advance, etc, so you can have images ready. (There might be some usable source code or even Apple sample code out there that does something like this, but I don't know of it off the top of my head.)

You may notice that some applications (not sure about the Photos app) have an intermediate stage where they load a very small thumb size image for all images, and scale it up to the render size, which acts as a placeholder until the full size version is loaded-- if the user scrolls past that image before the full size is loaded, the visible effect is nearly the same as if the image was there all along.

quixoto
That's interesting I never thought about doing the image reading on a separate thread. But it makes complete sense seeing as all of my I/O is being done on the UI thread right now. I assume I'd have to, on the main thread, have some code that would place a placeholder or something until the other thread updates it? I guess I understand, just don't know how I'd go about implementing it.
Alexander
"Placeholder" depends on your application, of course. You could either put nothing there, or put an empty UIImageView, or put some generic placeholder image or whatever. For threading, see the Apple docs on NSThread. There are a couple ways of handling it. If you've never done multithreaded code before, I'd recommend doing just the bare minimum in the secondary thread and don't touch any state directly-- use the performSelector stuff to communicate back to the main thread.
quixoto
Yeah well ideally I was thinking the placeholder could be the bare minimum really really small scale image, but then that would mean I'd still have to read off the disk (at least to place these tiny images) on the main thread right? I've worked minimally with NSThreads before but I think I'll read up a little on them in the docs
Alexander