Hello everyone.
I'm having a peculiar problem with CoreGraphics
/CoreAnimation
on the iPhone. To better explain how the problem manifests itself, I'll walk you through my current setup and illustrate with code where appropriate.
I'm trying to draw a bunch of preloaded images in a UIView
's CALayer
, but whenever the image displays, the app's memory usage spikes and the memory is not reclaimed whenever the image changes.
Preloading of the images is done by reading them through UIImage
's facilities, rendering them onto a Bitmap Context and extracting a CGImageRef
out of that context. The purpose of this is to decompress and scale the images, so that these operations do not occur on every draw. A similar recommendation can be found in an Apple Q&A on the matter (search for CGContextDrawImage
performance if you're curious). The context is set up with 8 bits per component and premultiplied alpha.
After the images are decompressed into a bitmap, they're stored in a NSArray
and are later assigned (not retained) to a custom UIView
subclass that does the drawing. I've tried various approaches to actually drawing the images, and by far the fastest method is directly setting the view's CALayer
contents
property. Other methods such as drawLayer:inContext:
and drawRect:
have varying impacts on the framerate, but they all exhibit the same memory behavior.
The problem is.. after the contents
property changes, I see a spike in memory in Instruments and that memory doesn't go down even after the image is no longer being displayed. Object Allocations stay constant, so my only guess is that CoreAnimation
is creating some implicit cache to speed up drawing. As I said however, that cache is not released when it should, and the gradual build-ups lead to a crash after only a couple of minutes of running.
The contents
property retains the object and I don't explicitly release it because I want the original images to stay in memory for the duration of the application's execution; on top of that, a high retain count wouldn't account for the memory spikes I see.
When examining the stack, I see that CoreAnimation
makes calls to functions such as CA::Render::copy_image
, which leads me to believe it's duplicating the layer's contents somewhere out of reach. I suppose there's a valid reason for this, but not knowing how and when to clear this is currently a show-stopping bug.
So can anyone with intricate knowledge of CA please explain to me if I'm doing something wrong and how I can work around this behaviour.
Thanks.