Improve Performance and Draw Your Own Strings on iPhone

Introduction

Programmers are lazy. If you are going to have some no-frills text on the screen that does not change too often an UILabel is the way to go. Changing the is very simple. It’s just a matter of:

myLabel.text = @"Change that text!";

What happens when you do this, every second for 45+ minutes (that’s 2700+ updates)?

Problem

I noticed that with every update of that label in the manner above my consumed ram was growing. Not a lot, but a few bytes. Enough though that after 2700+ times, it was causing some problems. I must be leaking I thought. Pop up Instruments with Leaks and test. No leakage apparent. Perhaps it was getting cached somewhere in UIKit?

As my application was going to be getting the proof-of-concept UI completely rewritten, UILabel was going to be a placeholder unless I could be a good lazy programmer and continue to use them.

However with UILabel seemingly cacheing the old labels or something, using them is out of the question.

Solution

Most programmers aren’t going to be updating their labels very often. Let alone 2700+ times every second.

My solution was a combination of Quartz2D (to change the color of the string) and NSString’s drawing categories.

- (void)drawRect:(CGRect)rect {
    // Get the current context so we can draw.
	CGContextRef context = UIGraphicsGetCurrentContext();
 
	// Set the fill color to white. 
	CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]); 
 
	//Draw in the specified rect
	[myString drawInRect:rect withFont:[UIFont fontWithName:@"Helvetica" size:16.0]  lineBreakMode:UILineBreakModeTailTruncation alignment:UITextAlignmentCenter];
 
}

Notes:

  • This assumes that you have a property myString declared somewhere.
  • You could probably improve performance a bit by cacheing the UIFont.
  • By drawing our own strings we lose the convenience of having a CALayer ready to use.

Conclusion

I used the above code (of course modified for posting) in my application and poof my application was no longer growing. Moreover, it actually feels a bit snappier.

UILabel is great for displaying static or mostly static text on the screen. However if you are going to be updating it with any frequency, it is advantageous to draw text manually. UILabel uses the drawInRect: or drawAtPoint: methods to draw anyways, calling them directly saves your phone from a lot of unneeded calls. This equates to less execution faster which in turn means more battery life for your users. A win for everybody.

This entry was posted in Cocoa, Development, iPhone, Objective-C. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">