Mark Dalrymple, who's way smarter than I am, wrote a blog post at Big Nerd Ranch about this very subject. Bottom line: the underscore is a good idea. I will summarize his post here just in case the link stops working in the future, but if possible you should read his post instead of my summary.
He wrote this post back when explicitly calling @synthesize
was mandatory. He advocated code such as:
// soapbubble.m
@synthesize viscosity = _viscosity;
@synthesize detergentBrand = _detergentBrand;
These days Xcode automatically and implicitly includes @synthesize
. And it does so using the prepended underscore so apparently Apple's engineers agree with Mark.
His first reason is stylistic. It allows you to easily see which variables are local and which are arguments in a setter:
- (void) setPonyName: (NSString *) ponyName {
[_ponyName autorelease];
_ponyName = [ponyName copy];
}
(This is a pre-ARC setter, so now this method would be completely unnecessary, but if the setter did anything more involved than simply releasing and assigning a value it would still apply.)
His second reason (and the one I think is more important) is that eliminates a certain class of bug that can be very difficult to track down.
This code:
self.ponyName = @"Mikey";
is identical to:
[self setPonyName: @"Mikey"];
Without the prepended underscore, this code is also valid:
ponyName = @"Mikey";
but it doesn't call the setter so any side effects in the setter don't occur. Again, in a situation where the setter does extra work besides changing the local variable's value this can cause big headaches. With the prepended underscore, that line would cause a compile error. You would have to be very explicit about wanting to set a local variable:
_ponyName = @"Mikey";
and, being the conscientious programmer you are, you would include a comment explaining exactly why you are performing this irregular maneuver.