August 7, 2011
MarkBernstein.org
 
Follow me on Twitter

iOS: Decorated objects

In C++, I use lots of decorator objects that wrap simple data types and add lots of functionality or adapt their syntax. For example, in Tinderbox an SRect is just a rectangle and can be cast at whim to an old-fashioned Macintosh Rect, but it also knows how to to unions and intersections, how to draw itself in various ways, how to wrap text inside its boundaries, and so forth.

If I happen to have a Rect and want an SRect, it costs a smidgeon of stack space and almost no time:

Rect r=CalculateMyRect(...);

SRect sr(r);

The overhead for the SRect is 16 bytes for the rectangle and something like 8 bytes for the object overhead, so it’s effectively free. Dismantling the SRect when you’re done with it is completely free, because there’s nothing to do in the destructor.

In Objective C, though, we have no stack objects. We have to create an object on the heap, and that object will eventually need to be (auto)released.

Rect r=CalculateMyRect(...);

SRect *mySRect=[[SRect alloc] initializeFrom: r]; // remember to release!

SRect *sr=[SRect fromRect: r]; // autoreleased

In principle, allocating and releasing this object might take a lot of work. Tinderbox blithely turns SRects into Rects and back whenever it wants, knowing this to be fast and easy. In particular, nearly ever function in Tinderbox’s numerous LayoutPolicy and DrawingPolicy classes do this at every call.

In C++, this might add up to thousands of microseconds for each view – a negligible cost.

In Objective C, this might add up to thousands of small autoreleased objects. Is that negligible? It might be, if the allocator is sufficiently clever.

How do you manage your decorated objects in Cocoa? Surely I’m not alone here. I’d love your advice. Email me.