Firstly, I recommend you use copy instead of retain(and assign) for NSString type of instance. If it's Mutable, then it gets copied; If not, then it just gets retained.
Maybe you'll like THIS DISCUSSION.
And for you question, the difference is that first one use the same name and the second one use the different name for iVar & property.
Actually, you have a METHOD 3 to use:
// in header
@interface Book : NSObject {
}
@property (nonatomic, copy) NSString *title;
// in implementation
@implementation Book
@synthesize title;
For @synthesize to work in the legacy runtime, you must either provide an instance variable with the same name and compatible type of the property or specify another existing instance variable in the @synthesize statement. With the modern runtime, if you do not provide an instance variable, the compiler adds one for you. For example, given the following class declaration and implementation.
Here is a sample code of official doc, you can make it clear( it includes difference between your METHOD 1 & METHOD 2):
@interface MyClass : NSObject {
float sameName;
float otherName;
}
@property float sameName;
@property float differentName;
@property float noDeclaredIvar;
@end
@implementation MyClass
@synthesize sameName;
@synthesize differentName=otherName;
@synthesize noDeclaredIvar;
@end
The compiler for the legacy runtime would generate an error at @synthesize noDeclaredIvar; whereas the compiler for the modern runtime would add an instance variable to represent noDeclaredIvar.
Note: iPhone applications and 64-bit programs on Mac OS X v10.5 and later use the modern version of the runtime. Other programs (32-bit programs on Mac OS X desktop) use the legacy version of the runtime. You can refer it HERE).
However, I suggest to use METHOD 1 or METHOD 3. As you can just use self.title in code, the property will help you manage the alloc & release. If you use METHOD 2, you may mix title with self.title(but _title is more clear, uh?). :)