159

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

Forge
  • 6,538
  • 6
  • 44
  • 64
Atma
  • 29,141
  • 56
  • 198
  • 299

9 Answers9

100

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;
Kelan
  • 2,296
  • 1
  • 15
  • 17
  • 80
    with auto-synthesizing properties this is no longer necessary. Xcode synthesizes a @property xxxx with an ivar named _xxxx behind the scenes. Neat. – CodeSmile Oct 13 '12 at 19:17
  • @LearnCocos2D Hi! A newbie to iOS here and there's something I need to clarify. For all this time what I did was declare the `property` in the .h file and in the .m fie I access it using `self` like so, `self.someProperty`. Is this the right way? Or should I be using the ivars in the code? – Isuru Jul 09 '13 at 05:13
  • setting the ivar doesn't run the property setter - you decide whether that is good idea or not for each particular case – CodeSmile Jul 09 '13 at 07:01
  • Noob question: why not use the ivars directly? why should I declare a separate var to hold the ivar? – Allen Aug 13 '13 at 10:24
  • 1
    @Allen, if I understand your question correctly: The separate var you're declaring is a pointer to the actual variable. This is important for a few reasons (that I know of) Firstly, when you pass a pointer into a function you're not duplicating it's value. You're simply telling the function where to find the value to use. This helps keep your used memory low (and also helps with alloc and dealloc of memory, which is important in the absence of 'garbage collection' which you'll find in Java) – David Sigley Aug 30 '13 at 13:34
  • There are also some neat tests you can run about the integrity of changing values when you access them directly. (Due to copies being made, often your original var will not change when you manipulate it) – David Sigley Aug 30 '13 at 13:38
  • @LearnCocos2D, no, you __don't__ _decide whether that is good idea or not_, as Apple states it [here](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE) – Iulian Onofrei Feb 23 '15 at 10:07
19

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. :)

Marc Charbonneau
  • 40,399
  • 3
  • 75
  • 82
  • 19
    From what I understand, Apple recommends against using the underscore prefix on method names (they reserve that for themselves as a convention for private methods), but they don't have any such recommendation about instance variable names. – Kelan May 05 '09 at 03:32
  • 9
    @Kelan In fact, Apple [encourages to do so](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE): "Usually, you should not access instance variables directly, instead you should use accessor methods (you do access instance variables directly in init and dealloc methods). To help to signal this, prefix instance variable names with an underscore (_), for example: \@implementation MyClass { BOOL _showsTitle; }" – dmirkitanov May 05 '12 at 19:38
  • I actually dont think Apple encourages us to do so, since all their own sample codes in the iOS Developer Library dont have the (_) in them. Apple also says that they have reserved it, which must mean that they use it internally for their own frameworks like UIKit etc. Which is why we shouldn't carelessly use it. But I see that, in the link you provided @kelan. They actually say in the "revision history" that it is "suitable" to use (_). I interpret is as we "can" use it if we want. – WYS Apr 23 '13 at 12:28
  • Apple's documentation which says not to use the underscore prefix for method names is [here](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282-1003829-BCIBDJCA). – ThomasW Jul 28 '15 at 05:49
9

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.

Peter DeWeese
  • 18,141
  • 8
  • 79
  • 101
  • It the other way around. private variable is underscored. the property not. and whem synthesizing them you couple them. – Justin Sep 25 '11 at 11:31
  • That is exactly as I describe, except that I called it a "member variable" instead of a "private variable". – Peter DeWeese Sep 26 '11 at 15:22
  • Ouch! This is asking for trouble… auto-synthesis will make the ivar _myString which means your setter won't work (because it then won't be able to tell your ivar from the method parameter). – geowar Apr 05 '15 at 15:38
  • Correct, which is why I added the edit at the end when apple added auto-synthesis. – Peter DeWeese Apr 06 '15 at 14:14
5

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?

smorgan
  • 20,228
  • 3
  • 47
  • 55
  • It's common in IDE's with intellisense; it will make your member/module/class variables show at the top of the list. Another common previx is "m_" – STW May 04 '09 at 22:55
  • 1
    if it doesn't mean anything how can you switch back and forth between _missionName and missionName like in my example above? My declaration looks like: Mission *aMission = [[Mission alloc] init]; aMission.missionName = @"a mission"; – Atma May 04 '09 at 22:58
  • 1
    One is an instance variable and the other is a property. You can't access instance variables with syntax like aMission.missionName, because that syntax doesn't work with pointers. – Chuck May 04 '09 at 23:47
  • Also, note that you are trying to operate on a Mission object, but the interface you have posted with the missionName property is a MissionCell. – smorgan May 05 '09 at 00:21
2

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.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Dipak Narigara
  • 1,796
  • 16
  • 18
1

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];
    }
}
Jason Fuerstenberg
  • 1,341
  • 13
  • 13
  • In this example it would be nice to see a comparison of the use of self.image (or [self image]) as well. When is it better to use self.image and when is it better to use _image? – Boeckm May 01 '12 at 14:33
  • 2
    @Boeckm: Generally, you should use `self.image`, which accesses the property. The only time you should access the instance variable, `_image`, directly is within `init` methods and the `dealloc` method, when calling any other method may be risky (since the object is half-initialized or half-deallocated). – Peter Hosey May 03 '12 at 02:25
1

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

RayInNoIL
  • 817
  • 10
  • 18
0

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

SARATH SASI
  • 1,395
  • 1
  • 15
  • 39
  • 2
    if you only need the variable in the same class just declare it in .m file itself then it will allow you to call without self nor the underscore – Ansal Antony Feb 23 '16 at 16:20
0

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;

}
pkamb
  • 33,281
  • 23
  • 160
  • 191