views:

136

answers:

4

I've noticed in some of the examples ive seen that you will set a engine( class variable ) to a _engine ( ivar ). I don't get it. What's going on here?

Here is an example of what I'm saying: @synthesize engine = _engine, delegate = _delegate

+9  A: 

This syntax maps a property to an instance variable (ivar) with a different name.

So:

@synthesize engine = _engine;

will create property accessor methods that access the _engine ivar instead of engine. You can still access the propery as:

object.engine

More info in the Apple developer documentation on properties (section Property Implementation Directives)

Philippe Leybaert
A: 

If the name of the ivar does not exactly match the name of the synthesized var then you need to map the ivar to the var. You might want to do this if you like prefixing your ivars with an underscore.

rein
+4  A: 

The author wanted to make sure that there was no confusion between accessing the ivar directly and accessing via the setter/getter. If the names are the same, the usual case, it is easy to write: engine = 0 instead of self.engine = 0; For an ivar that needs to be retained such as NSString this can cause errors in the retain counts.

There is also historic precedence of naming ivars with a leading "_", "m" or "f" so they wpuld be readily recognized as ivars.

zaph
+3  A: 

The @synthezise keyword tells the Objective-C compiler to generate a getter and a setter method for your property. If you have defined:

@property(copy,nonatomic) NSString* name;

Then @synthesize name; will create these two methods for you, so that you do not have to implement them:

-(NSString*)name;
{
  return name;
}
-(void)setName:(NSString*)newName;
{
  if (name != newName) {
    [name release];
    name = [newValue copy];
  }
}

By default the name of the instance variable that is used as the backing store for the synthesized property is named the same as the property. This is not always what you want, and you can then synthesize as @synthesize name = _otherName; to tell the compiler to instead generate this code for you:

-(NSString*)name;
{
  return _otherName;
}
-(void)setName:(NSString*)newName;
{
  if (_otherName != newName) {
    [_otherName release];
    _otherName = [newValue copy];
  }
}

The reason you usually prefix the instance variables that are used as backing stores for properties with a underscore character '_' is to make help you to remember not to access them directly.

PeyloW
In your setters, `name` and `_othername` should be autoreleased, not regularly released. If they are the same pointer to the passed parameter `newName` then it may become prematurely deallocated.
dreamlax
Correct, I updated the example to reflect this, but did not use autorelease since this is not what the compiler do.
PeyloW
Autoreleasing would be quite a bit more expensive than a simple compare, but I personally do it anyway for no particular raisin.
dreamlax
Don't autorelease, just retain the new one first, then release, then assign (or only do anything if current != new).
Mk12