Why in the newest version of Xcode (dp-4) are variables declared with retain,nonatomic
made to use the underscore before the variable name? Does this create some sort of type safety?
For example, I create a property:
@property (retain, nonatomic) IBOutlet UILabel *name;
Unless I change the variable inside the dealloc
to not have the _, I have to do:
@synthesize name = _name;
Why is this?
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.
"_name" in your @synthesize name = _name, is just a variable name created automatically by your Xcode. This is done because @synthesize just creates setters and getters and if you don't use _name, it'll take your property name, i.e. name (in this case) and finally leads to bugs in your app. _name is just a naming convention. You can use any variable name in place of _name. So that @synthesize will use that variable name in its implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With