6

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

So i have found out that you have to use underscore when synthesizing properties and that doesn't make a single bit of sense to me.

So, let's start. In our .h file we write this line:

@property (nonatomic) double speed;

In our .m file we do this:

@synthesize speed = _speed;

Why? As far as I know, property makes an instance variable and creates setters and getters for it. But what the hell does line

@synthesize speed = _speed 

do? As common sense tells me, we assign value in _speed to speed. Okay. Where did we declare _speed? Why doesn't compiler give us an error? What is it supposed to mean? Why such an obfuscated code?

My questions here:

What happens if I do just

@synthesize speed;

without _speed, will I get error or some bugs? What is the reason after this syntax? What were they thinking when making it? Where does _speed come from? What is it? Is it a pointer or a real value? What is going on?

Community
  • 1
  • 1
Dvole
  • 5,725
  • 10
  • 54
  • 87
  • Also see http://stackoverflow.com/questions/3521254/prefixing-property-names-with-an-underscore-in-objective-c – msk Jul 12 '12 at 19:39
  • 4
    This has been asked about twice a day since properties were introduced... I'm only exaggerating slightly. – Matt Wilding Jul 12 '12 at 19:41
  • It surly is, but as LLVM Clang envolve, the answers also envolve. You can cut all the crap and only keep the property declaration as of today. That wasn't true last week. – fabrice truillot de chambrier Jul 12 '12 at 19:52
  • 1
    @fabricetruillotdechambrier Indeed, I've been enjoying cutting all the crap with the recent Xcode betas. It's still surely best to amend the previous 800 question and answers than add more to the pool =) – Matt Wilding Jul 12 '12 at 19:58
  • 4
    Here's 16 duplicates: http://stackoverflow.com/q/5582448/ http://stackoverflow.com/q/6049269/ http://stackoverflow.com/q/2371489/ http://stackoverflow.com/q/7174277/ http://stackoverflow.com/q/5659156 http://stackoverflow.com/q/837559/ http://stackoverflow.com/q/6146244/ http://stackoverflow.com/q/10651535/ http://stackoverflow.com/q/6124109/ http://stackoverflow.com/q/8145373/ http://stackoverflow.com/q/3521254/ http://stackoverflow.com/q/6064283/ http://stackoverflow.com/q/9696359/ http://stackoverflow.com/q/5521499/ http://stackoverflow.com/q/5466496/ http://stackoverflow.com/q/2114587/ – jscs Jul 12 '12 at 20:31

7 Answers7

5

Well, _speed is the instance variable used by the property. If you really want to declare it fully, you need to write:

@interface Foo
{
    double _speed;
}

@property double speed;

@end

@implementation Foo

@synthetize speed = _speed;

@end

Now Xcode 4.4 is unleashed, most of that stuff is unnecessary and should be omitted for sanity.

Basically, all you have to do is:

@interface Foo

@property double speed;

@end

No instance variable, no @synthetize, and everything still works as before. You can either use self.speed or self->_speed for direct access.

1

okay you don't have to do this...

However by doing so means that in your implementation you cannot use the non underscore name of that property, because in fact by doing so you would be getting mixed up with accessing the iVar directly rather then through the property.

So in other words by doing this:

@synthesize myProperty;

In your code you can reference it by myProperty (iVar) or self.myProperty (property - with the access rules - readonly/readwrite, getter, setter etc...) this can of course be confusing if you are using some kind of rules like:

@property(nonatomic, retain, getter = anotherProperty) NSNumber myProperty

By accessing this with myProperty in code, you would expect to get value of anotherProperty

This would only be possible by doing:

self.myProperty

So in Objective-C we can do the following to avoid this:

@synthesize myProperty = _myProperty;

Therefore in code it is actually an error to reference myProperty directly, instead you must do self.myProperty (property access) or _myProperty (iVar access).

Daniel
  • 23,129
  • 12
  • 109
  • 154
1

You do not HAVE to do that. It is just common practice. The ...=_speed will create an property named _speed and its setter and getter will be named after speed. That allows you to distinguish between

self.speed = value;

and

speed = value; 

because the latter will create a compiler error.

_speed = value; 

would be correct in that case.

That helps avoiding retain/release related errors because the setter will retain the object and the simple assignmen will not. (self.speed = ... will call the setter!)

If you omit the "=_speed" on the synthesize statement then the property will be named "speed" only. If you don't make any mistakes, then this will work perfectly fine.

Hermann Klecker
  • 14,039
  • 5
  • 48
  • 71
0

Its a naming convention, you don't have to do it. People tend to do this so that they can distinguish between the instance variable and the property.

Usually it goes

.h

@interface myClass : NSObject
{
    NSNumber *_speed
}

@property (nonatomic, strong) NSNumber *speed;

.m

@implementation
@syntesize speed = _speed;
Karoly S
  • 3,180
  • 4
  • 35
  • 55
0

Nothing bad will happen -- it's fine to just write @synthesize speed. Using _speed just makes the underlying instance variable _speed instead of speed. Most people do this to keep from accidentally accessing the ivar directly, instead of through thr getter.

rdelmar
  • 103,982
  • 12
  • 207
  • 218
0

From the documentation

@synthesize speed = _speed; will point the property speed to the instance variable _speed.

You do not have to do this. @synthesize speed works just fine.

quellish
  • 21,123
  • 4
  • 76
  • 83
0

In environment with manual memory management:

Why do I need an instance variable name at all?

  1. You need to release memory which may be used by your properties in the dealloc
  2. You may use self.field = nil but this approach may cause problems
  3. So you need an instance variable which is used behind this property so you can [_field release]; it in dealloc.

The same if you need to access your property in the initializer.

Why do I need an underscore in the instance variable name?

  • To never accidentally use ivar directly and break memory management contract for the property

@property (retain) UILabel *label;

...

@synthesize label;

...

-(void)viewDidLoad {
   [super viewDidLoad];

   label = [[[UILabel alloc] initWithFrame:frame] autorelease];
}

here by accidentally missing self. you made label potential 'dangling pointer'. If you used @synthesize label = _label; above code would produce a compiler error.

  • Local variables or method parameter names often tend to be the same as the property name - if you use underscored instance variable it won't cause any problems
Community
  • 1
  • 1
Max O
  • 997
  • 8
  • 13