Graphics Reference
In-Depth Information
The final option is to load the image using UIKit as normal, but immediately draw it into a
CGContext . An image must be decompressed before it is drawn, so this forces the
decompression to happen immediately. The advantage of doing this is that the drawing can
be done on a background thread (like the loading itself) so it need not block the UI.
There are two approaches you can take when pre-drawing an image for the purpose of
forcing decompression:
Draw a single pixel of the image into a single-pixel sized CGContext . This still
decompresses the entire image, but the drawing itself takes essentially no time. The
disadvantage is that the loaded image may not be optimized for drawing on the
specific device and may take longer to draw in future as a result. It is also possible
that iOS may discard the decompressed image again to conserve memory.
Draw the entire image into a CGContext , discard the original, and replace it with a
new image created from the context contents. This is more computationally expensive
than drawing a single pixel, but the resultant image will be optimized for drawing on
that specific iOS device, and since the original compressed image has been discarded,
iOS can't suddenly decide to throw away the decompressed version again to save
memory.
It's worth noting that Apple specifically recommends against using these kinds of tricks to
bypass the standard image decompression logic (which is not surprising—they chose the
default behavior for a reason), but if you are building apps that use a lot of large images,
then you sometimes have to game the system if you want great performance.
Assuming that using +imageNamed: isn't an option, drawing the entire image into a
CGContext seems to work best. Although you might think that the extra drawing step would
make this perform unfavorably compared with the other decompression techniques, the
newly created image (which is optimized specifically for the particular device on which it
was created) seems to draw faster on every subsequent use than if you keep the original.
Also, if you intend to display the image at a smaller-than-actual size, redrawing it at the
correct size for display on a background thread once and for all will perform better than re-
applying the scaling every time it's displayed (although in this example, our loaded images
are the correct size anyway, so that particular benefit doesn't apply here).
If you modify the -collectionView:cellForItemAtIndexPath: method to redraw the
image prior to display (see Listing 14.3), you should find that the scrolling is now perfectly
smooth.
Listing 14.3 Forcing Image Decompression Prior to Display
- ( UICollectionViewCell *)collectionView:( UICollectionView *)collectionView
cellForItemAtIndexPath:( NSIndexPath *)indexPath
{
//dequeue cell
UICollectionViewCell *cell =
Search WWH ::




Custom Search