Monday, 31 October 2011

What's the benefit of having 2 names for the same variable?

I was following this tutorial called Cocos2d Sprite Tutorial, and noticed as below, the variables were first declared in the header file with an extra "_" underscore character at the front.

    CCSprite *_dragon;
    CCAction *_flyAction;
    CCAction *_moveAction;

But then at the @property declaration, the underscore character was removed.

@property (nonatomic, retain) CCSprite *dragon;
@property (nonatomic, retain) CCAction *flyAction;
@property (nonatomic, retain) CCAction *moveAction;

And then in the main ".m" file, both names were used as below with the "=" sign at the "@synthesize".

@synthesize dragon = _dragon;
@synthesize moveAction = _moveAction;
@synthesize flyAction = _flyAction;

And also inside the code both names were referenced as shown below:

        self.dragon = [CCSprite spriteWithSpriteFrame:frame1];
        _dragon.position = ccp( s.width/2-80, s.height/2);

But why? This is the not the first time I saw people doing that, but I don't understand the benefit at all, won't it be very confusing having 2 names for the same variable?


  1. My understanding is it has to do with avoiding accessing instance variables directly.

    So when you "@synthesize" an instance variable, you're essentially creating getter/setter methods to access those variable values. By convention, you always want to use those getter/setter methods to retrieve/update the values held by the instance variables. If you access them directly (by name), you circumvent the getter/setter methods you created, which I assume is bad somehow (inefficient?).

    The "dragon = _dragon" convention is for convenience. So instead of always writing

    self.dragon = value;

    you can say

    _dragon = value;

    In fact, I believe you could say dragon equals anything, such as

    @synthesize dragon = puffTheMagicDragon;

    then in your code you would write

    puffTheMagicDragon = value;


    puffTheMagicDragon.position = value;

    The underscore nomenclature (_variable) is just convenient shorthand to avoid having to give the variable two distinct names. I'm not sure of the mechanics, but somehow using this arbitrary "alias" for your instance variable avoids accessing the variable directly.