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 UILabel
s:
@interface XXView : UIView
@property (nonatomic, retain) UILabel *title;
@property (nonatomic, retain) UILabel *someKindOfDescription;
@end
Approach 1: Only use properties to create and setup the UILabel
s:
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.
Permanent link to this post: http://xinsight.ca/blog/saving-objc-method-calls/
Older: In-App Purchase content downloads in iOS6
Newer: Implications of Free In-App Purchases