Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Xcode automatically create variables with underscores?

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?

like image 470
GoGauchos Avatar asked Feb 17 '23 23:02

GoGauchos


2 Answers

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.

like image 57
SSteve Avatar answered May 16 '23 07:05

SSteve


"_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.

like image 20
AKB Avatar answered May 16 '23 07:05

AKB