Saving objective-c method calls

04 Feb 2013

In objc_msgSend Is Not Your Bottleneck Ash Furrow makes the great point that developers shouldn’t obsess about avoiding objective-c method calls – it’s premature optimization.

I agree. Using instance variables instead of properties leads to inconsistent and more brittle code. But the example provided in the article - instantiating a UILabel - is the exact place where avoiding properties leads to cleaner, better code.

Consider the common case where you need a couple of UILabels:

@interface XXView : UIView
@property (nonatomic, retain) UILabel *title;
@property (nonatomic, retain) UILabel *someKindOfDescription;
@end

Approach 1: Only use properties to create and setup the UILabels:

self.title = [[UILabel alloc] initWithFrame:CGRectMake(...)];
	self.title.textColor = [UIColor whiteColor];
	self.title.shadowColor = UIColorFromRGBHex(0x222222);
	self.title.shadowOffset = CGSizeMake(0, 1);
	self.title.textAlignment = UITextAlignmentCenter;
	self.title.text = @"Heading";
	self.title.font = [UIFont boldSystemFontOfSize:24];
	[self.view addSubview:self.title];
	
	self.someKindOfDescription = [[UILabel alloc] initWithFrame:CGRectMake(...)];
	self.someKindOfDescription.textColor = [UIColor whiteColor];
	self.someKindOfDescription.shadowColor = UIColorFromRGBHex(0x222222);
	self.someKindOfDescription.shadowOffset = CGSizeMake(0, 1);
	self.someKindOfDescription.textAlignment = UITextAlignmentCenter;
	self.someKindOfDescription.text = @"Lorum ipsum";
	self.someKindOfDescription.font = [UIFont systemFontOfSize:14];
	[self.view addSubview:self.someKindOfDescription]

Approach 2: Create and reuse a local variable, only assign the property once:

UILabel *label;
	
	label = [[[UILabel alloc] initWithFrame:CGRectMake(...)] autorelease];
	label.textColor = [UIColor whiteColor];
	label.shadowColor = UIColorFromRGBHex(0x222222);
	label.shadowOffset = CGSizeMake(0, 1);
	label.textAlignment = UITextAlignmentCenter;
	label.text = @"Heading";
	label.font = [UIFont boldSystemFontOfSize:24];
	[self.view addSubview:label];
	self.title = label;
	
	label = [[[UILabel alloc] initWithFrame:CGRectMake(...)] autorelease];
	label.textColor = [UIColor whiteColor];
	label.shadowColor = UIColorFromRGBHex(0x222222);
	label.shadowOffset = CGSizeMake(0, 1);
	label.textAlignment = UITextAlignmentCenter;
	label.text = @"Lorum Ipsum";
	label.font = [UIFont systemFontOfSize:14];
	[self.view addSubview:label];
	self.someKindOfDescription = label;

Both approaches are verbose - the 2nd one is even a few lines longer - but the huge benefit of #2 is that the code for each UILabel is almost exactly the same, so I can copy and paste the first label and only have to edit the property name on the last line. That saves a bit of typing, but mainly it avoids the error where I copy/paste and forget to edit the property name on all those lines. (Usually that happens on addSubview: so one label is missing and the other is added twice.)

Another nice benefit is that I can put the whole UILabel chunk of code into an Xcode snippet and never have to type it again.

It’s just icing on the cake that it saves a bunch of cycles.


Older: In-App Purchase content downloads in iOS6

Newer: Implications of Free In-App Purchases


View Comments

Related Posts

Recent Posts