The @synthesize directive tells the compiler to create an instance variable for your declared property.
for example, if you declare in your .h file:
@property (nonatomic, retain) NSString *foo;
and in your .m file
@synthesize foo;
This will generate a private instance variable NSString *foo
, as well as accessor methods:
- (void)setFoo:(NSString *)foo;
- (NSString *)foo;
Code within the class may look like
self.foo = @"bar"; // set through accessor - dot notation
[self setFoo:@"bar"]; // set through accessor - method notation
foo = @"bar"; // direct assignment
If you are not using ARC, the second example would be unsafe, as you're assigning an autoreleased string instead of a retained string. This would be released and you're left with a dangling pointer, which would crash when accessed.
What you probably meant to do was to use the accessor, or to retain the object on assignment e.g. foo = [@"bar" retain];
By declaring a different variable in your .m file:
@synthesize foo = _foo;
What you're doing is telling the compiler to create the private instance variable NSString *_foo
instead.
I prefer to do it this way, as the underscore makes it more clear in your implementation when you are accessing the instance variable directly vs. through an accessor method. Especially when using dot notation. As in the example above, the code would look like:
_foo = @"bar"; // direct assignment
You can instantly see that you're assigning to an ivar directly, and should be aware of the memory semantics involved.