Reputation: 1901
I have seen a lot of code like this
header.h
@interface Foo : NSObject
{
NSString *str;
}
@property(nonatomic, retain) NSString *str;
@end
and then in implementation
@implementation Foo
@synthesize str = _str;
@end
I can't understand what is the benefit of using such assignment ?
@synthesize str = _str;
Upvotes: 1
Views: 294
Reputation: 6844
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.
Upvotes: 0
Reputation: 26952
It is just a common naming convention.
It is so that in your implementation, you can distinguish accessing a variable directly against accessing via the property accessor.
If you try and access str in your code, like [str length], the code won't compile. You either need to do [self.str length] or [_str length].
... and as it's an NSString immutable property, use copy
, not retain
.
Upvotes: 3
Reputation: 34912
@synthesize str = _str;
will mean that the instance variable that is synthesised for the str
property is called _str
. In your code you therefore have a mismatch between it and the declared instance variable. So you'll actually end up with 2 instance variables, one called str
and one called _str
.
You want to do this:
@interface Foo : NSObject
@property(nonatomic, retain) NSString *str;
@end
@implementation Foo
@synthesize str = _str;
@end
Or this:
@interface Foo : NSObject {
NSString *str;
}
@property(nonatomic, retain) NSString *str;
@end
@implementation Foo
@synthesize str;
@end
Or obviously rename the declared instance variable, _str
.
There's lots of questions on SO already about whether or not to prefix with _
such as - Prefixing property names with an underscore in Objective C .
Upvotes: 3