how to instantiate a happy santa in objective c

Mon, Dec 19, 2011

It’s that time of year again when The Big Man gets on his sleigh and distributes prezzies to the kids. Unfortunately there’s a global recession in full swing and Santa’s bank manager wants some accountability from The Man In Red this time. In previous years Santa has tended to get quick loans or maxed out on his credit card to pay the Elves as although Santa is the front man, it’s the wee folk that do all the work of compiling lists and making presents to distribute. To make this as smooth as possible they’ve designed the Present Distribution Process (PDP):

The Present Distribution Process

The process is nice and simple. During the year, the Elves compile a list of presents that kids have requested and on Christmas Eve they give the list to Santa who programs the PDP using the Software Development Kit (SDK) the Elves have developed. The SDK is a set of classes for Santa to easily put together an automated sleigh journey. Santa studies the present list, programs the journey using classes from the SDK, compiles his code into a Present Distribution Route (PDR) and uploads the PDR to the sleigh. Santa then hops on and cracks open a bottle of mulled wine while the sleigh does its job of delivering the presents.

However this year, to add to Santa’s woes, the Elves have jumped on the mobile bandwagon and have ported the PDP to iOS and Objective-C and a small bug has crept into the SDK. It’s very subtle but will end up bankrupting Santa. Our job is to investigate this bug and keep Santa solvent!

So what is the bug? It’s do with the cost of each present. The cost is stored in a Present class:

@interface Present : NSObject

  • (void)setPresentCost:(NSInteger)costInPounds;
  • (NSInteger)getPresentCost;


@implementation Present

NSInteger presentCost;

  • (void)setPresentCost:(NSInteger)costInPounds { presentCost = pounds }

  • (NSInteger)getPresentCost { return presentCost; }


and the PDR contains an array of Present classes. However, it only sets the cost of a Present if the automated sleigh can deliver it. Otherwise it sets the cost as zero so the bank manger only pays the Elves for the presents that were delivered.

This is where the bug becomes apparent. The Elves have used what’s known as a ‘global variable’ in the Present class. Being Java gurus, the Elves thought that the presentCost variable would act like an instance variable in Objective-C as that’s what it does in Java. But in Objective-C it’s a bit of a hybrid between a class variable and an instance variable. You see, you can’t have class variables in Objective-C but global variables act in almost the same way but using instances of the class instead. What happens when the PDR invokes setPresentCost: is that invocation sets the presentCost for all Present classes who have already had their cost set. Including the ones which weren’t delivered and had a presentCost of zero! While Santa is merrily quaffing mulled wine on his automated sleigh, his bank account is going into meltdown!

Present *presentForJohnny = [[Present alloc] init];
Present *presentForJimmy = [[Present alloc] init];
Present *presentForHarry = [[Present alloc] init];

// deliver Johnny’s present [presentForJohnny setPresentCost:100];

// couldn’t deliver Jimmy’s present [presentForJimmy setPresentCost:0];

// deliver Harry’s present [presentForHarry setPresentCost:1000];

The PDR has calculated that Santa owes the Elves 1100 pounds. 100 for Johnny’s present and 1000 for Harry’s. Posh kid is Harry you see. There’s no cost for Jimmy as the sleigh couldn’t deliver his present. Later that night back at base the Elves will download the logs from the automated sleigh and see a PresentDeliveryException (PDE) due to a jammed present chute. Perhaps because of the exceptionally low temperatures that night caused by global warming.

But remember, there’s a bug in the PDP SDK which has caused the PDR to incorrectly calculate the cost of the presents. As the SDK is using a global variable, only the last value of presentCost will be used, IN ALL PRESENTS. i.e. Santa is out of pocket to the tune of 3000 pounds! Setting Harry’s presentCost to 1000 has made presentCost in all the other Present classes the same. Even Jimmy’s which should have been zero. Gulp!

As you can see, Santa is a broken man. The cost of each present depends on the fuel used to reach the correct house as well as the manufacturing cost of the present. The manufacturing cost is known but the runtime costs such as fuel consumption on that present leg of the journey and other factors such as sleigh depreciation are lost. As Santa downs another bottle of mulled wine back at base and holds his head in his hands he decides to hire a software developer to save his diminishing pile of cash.

The software developer quickly spots the bug in the SDK and roundly chides the Elves for their lack of unit testing and fixes the bug using a proper instance variable:

@interface Present : NSObject

@property (nonatomic, assign) NSInteger presentCost;


@implementation Present

@synthesize presentCost;


Using the @property compiler directive, the Present class gets an implicit setter/getter for the¬†presentCost instance variable which is unique to each instance of the Present class. That’s why it’s called an instance variable. It’s not a global instance variable like it was when the Elves made a mess of developing the SDK so setting the presentCost in another Present class has no effect on existing presentCost values in presents already delivered.

Hoorah, the software developer has saved Santa from certain bankruptcy! Merry Chistmas and a fun filled ho ho ho to you all!

comments powered by Disqus