It’s right there in the CALayer documentation:
An object that provides the contents of the layer. Animatable.
@property(retain) id contents
A layer can set this property to a
CGImageRefto display the image as its contents. The default value is
There’s exactly one thing a developer can assign to a layer’s
contents property: a
CGImageRef. So why is the property declared to be an
Back Up a Second.
id is Objective-C’s general object type. It’s like a
void* for objects. We’ve already got kind of a problem here — how is a
CGImageRef the same as an Objective-C object? — but short story, Core Foundation pseudo-objects (
CFTypes) — and pseudo-objects that derive from
CFType (like Core Graphics types) — are set up such that they satisfy the requirements of
id. This is a prerequisite for, but not the same as, toll-free bridging. Maybe Jerry will write a post about that in the future!
It’s true that there’s only one thing a developer can write to a layer’s contents, but that’s only half of what a property does. If you read the contents back, you won’t necessarily end up holding a
CGImageRef. If the layer has been drawn into, using delegate methods (
drawLayer:inContext:) or subclassing (
drawInContext:), you’ll actually get an opaque internal type called
CABackingStore. This is, as the name implies, a pixel buffer holding the stuff you see in the layer.
Sounds like we have another problem! There’s no header file for
CABackingStore; there’s nothing a well-meaning developer can do with it. Or is there? Although the documentation specifies that developers should set layers’ contents to
CGImageRefs, they are actually perfectly happy to share generic contents. That means cloning a layer is as easy as
layerB.contents = layerA.contents; no cast required, since they’re both type
id! (…if they’re both in the same layer hierarchy*, which on iOS they almost certainly will be.)
The documentation doesn’t make it clear, but you can set a
contents property to either a
CGImageRef, or the contents of another layer. When querying the contents of a layer, don’t expect to get back a
CGImageRef, but do expect something that can serve as the contents of something else. Even if new types (internal or external) are added to the API, this will always hold true.