Here's a quick example of how it can be useful to use the name change:
@interface MyClass : NSObject {
    NSString *myString;
}
@property (nonatomic, retain) NSString *myString;
- (NSString *)stringTreatment:(NSString *)str;
@end
@implementation MyClass
@synthesize str = _str;
- (id)init {
    self = [super init];
    if (self) {
        self.str = [NSString string];
    }
    return self;
}
- (NSString *)stringTreatment:(NSString *)str {
    return [str uppercaseString];
}
@end
If you wouldn't have synthesized str as _str, you would get a warning in that stringTreatment method saying that the local declaration of str hides the instance variable.
Also, in your code, you could be assigning a value to _str and have an external class call [MyClass str] and it would return it.
So, to make a long story short, "str" remains the name of your property and "_str" is the internal reference to that property. For example, you won't be able to use [MyClass _str], that won't work. Makes sense?
Hope this helps.