Atma
Atma

Reputation: 29805

How does an underscore in front of a variable in a cocoa objective-c class work?

I've seen in a few iPhone examples that attributes have used an underscore _ in front of the variable. Does anyone know what this means? Or how it works?

An interface file I'm using looks like:

@interface MissionCell : UITableViewCell {
    Mission *_mission;
    UILabel *_missionName;
}

@property (nonatomic, retain) UILabel *missionName;

- (Mission *)mission;

I'm not sure exactly what the above does but when I try to set the mission name like:

aMission.missionName = missionName;

I get the error:

request for member 'missionName' in something not a structure or union

Upvotes: 158

Views: 53402

Answers (9)

pkamb
pkamb

Reputation: 35052

Missing from the other answers is that using _variable prevents you from absentmindedly typing variable and accessing the ivar rather than the (presumedly intended) property.

The compiler will force you to use either self.variable or _variable. Using underscores makes it impossible to type variable, which reduces programmer errors.

- (void)fooMethod {

    // ERROR - "Use of undeclared identifier 'foo', did you mean '_foo'?"
    foo = @1;

    // So instead you must specifically choose to use the property or the ivar:

    // Property
    self.foo = @1;

    // Ivar
    _foo = @1;

}

Upvotes: 0

SARATH SASI
SARATH SASI

Reputation: 1425

instead of underscore you can use self.variable name or you can synthesise the variable to use the variable or outlet without underscore .

Upvotes: 0

Dipak Narigara
Dipak Narigara

Reputation: 1806

This is only for the naming convention of synthesize properties.

When you synthesize variables in the .m file, Xcode will automatically provide you _variable intelligence.

Upvotes: 2

RayInNoIL
RayInNoIL

Reputation: 907

This seems to be the "master" item for questions about self.variableName vs. _variablename. What threw me for a loop was that in the .h, I had:

...
@interface myClass : parentClass {
className *variableName;    // Note lack of _
}

@property (strong, nonatomic) className  *variableName;
...

This leads to self.variableName and _variableName being two distinct variables in the .m. What I needed was:

...
@interface myClass : parentClass {
className *_variableName;    // Note presence of _
}

@property (strong, nonatomic) className  *variableName;
...

Then, in the class' .m, self.variableName and _variableName are equivalent.

What I'm still not clear on is why many examples still work, even tough this is not done.

Ray

Upvotes: 1

Peter DeWeese
Peter DeWeese

Reputation: 18343

The only useful purpose I have seen is to differentiate between local variables and member variables as stated above, but it is not a necessary convention. When paired with a @property, it increases verbosity of synthesize statements – @synthesize missionName = _missionName;, and is ugly everywhere.

Instead of using the underscore, just use descriptive variable names within methods that do not conflict. When they must conflict, the variable name within the method should suffer an underscore, not the member variable that may be used by multiple methods. The only common place this is useful is in a setter or in an init method. In addition, it will make the @synthesize statement more concise.

-(void)setMyString:(NSString*)_myString
{
    myString = _myString;
}

Edit: With the latest compiler feature of auto-synthesis, I now use underscore for the ivar (on the rare occasion that I need to use an ivar to match what auto-synthesis does.

Upvotes: 9

Jason Fuerstenberg
Jason Fuerstenberg

Reputation: 1351

Having an underscore not only makes it possible to resolve your ivars without resorting to using self.member syntax but it makes your code more readable since you know when a variable is an ivar (because of its underscore prefix) or a member argument (no underscore).

Example:

- (void) displayImage: (UIImage *) image {

    if (image != nil) {
        // Display the passed image...
        [_imageView setImage: image];
    } else {
        // fall back on the default image...
        [_imageView setImage: _image];
    }
}

Upvotes: 1

Marc Charbonneau
Marc Charbonneau

Reputation: 40513

It's just a convention for readability, it doesn't do anything special to the compiler. You'll see people use it on private instance variables and method names. Apple actually recommends not using the underscore (if you're not being careful you could override something in your superclass), but you shouldn't feel bad about ignoring that advice. :)

Upvotes: 19

Kelan
Kelan

Reputation: 2276

If you use the underscore prefix for your ivars (which is nothing more than a common convention, but a useful one), then you need to do 1 extra thing so the auto-generated accessor (for the property) knows which ivar to use. Specifically, in your implementation file, your synthesize should look like this:

@synthesize missionName = _missionName;

More generically, this is:

@synthesize propertyName = _ivarName;

Upvotes: 99

smorgan
smorgan

Reputation: 21599

It doesn't really mean anything, it's just a convention some people use to differentiate member variables from local variables.

As for the error, it sounds like aMission has the wrong type. What it its declaration?

Upvotes: 5

Related Questions