Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIImageView vs UIView w/ Image - efficiency

This is not really a question about addressing a specific problem but more a request to be pointed in the right direction.

I am making an app where I am loading several images (saved as JPGs) onto a screen at the same time and this has to be the way it is, I can't unload any of them because they are all being shown at once.

I tried loading 30 images at about 800px*600px resolution naively thinking that it only loads the 'compressed' size of the pictures into memory (this being about 200 KB) - so a total of 6 MB? Of course, several memory warnings later, I realised how stupid I was. So i now re-size them to about 400px*300px each and my iPhone 4S just about copes with the memory requirements.

I originally used a UiView where in the drawRect I drew a custom drawn image but changing over to using a UIImageView improved the situation dramatically. The app is so much faster and responsive. I also found that switching off rasterization in my layer made a huge difference in performance.

These sorts of 'discoveries' have taken me hours to work out and what I was wondering was if there are particular design patterns or resources that I can use to load my images to the screen as efficiently as possible; mainly regarding using as little memory as possible - are there are good rules of thumb? Why did using UIImageView vs UiView w/ image make such a difference?

Would be very grateful if someone could help.

Thanks.

like image 913
BYZZav Avatar asked Jan 11 '12 22:01

BYZZav


People also ask

What is the difference between a UIImage and a UIImageView?

UIImage contains the data for an image. UIImageView is a custom view meant to display the UIImage .

What is UIImageView in Swift?

A view that displays a single image or a sequence of animated images in your interface.


1 Answers

Implementing -drawRect: causes the system to allocate a bitmap image of the same size as your view (after all, you need a buffer to draw in to). If all you're doing is drawing an image you've already loaded, then in one fell swoop you've doubled the memory usage for that image (because you have the copy you loaded, and the second copy you just drew).

Similarly, rasterizing layers requires allocating bitmap images the same size as the layer, so it has a buffer to rasterize into. So turning that on sucks up memory as well (proportional to the size of the layer).

The basic rule of thumb is, don't do extra work. Using -drawRect: to draw an image is extra work. Rasterizing a layer is extra work (though, depending on what the layer is, this may be a one-time performance cost (and a constant memory cost) in order to save on performance later, e.g. if it's a CAShapeLayer or if it's drawing shadows). Keeping large images in memory that you always scale down before rendering to screen is extra work (just scale it down once when you load the image, and keep the scaled copy around).

Another thing to keep in mind is, if your goal is to draw images, you should try to use UIImageView if you possibly can. It's generally the fastest and cheapest way to get an image to the screen, and it's reasonably flexible.

like image 138
Lily Ballard Avatar answered Oct 05 '22 23:10

Lily Ballard