我见过很多像这样的代码
header.h
@interface Foo : NSObject
{
NSString *str;
}
@property(nonatomic, retain) NSString *str;
@end
然后在实施中
@implementation Foo
@synthesize str = _str;
@end
我无法理解使用此类作业有什么好处?
@synthesize str = _str;
答案 0 :(得分:3)
这只是一种常见的命名惯例。
在您的实现中,您可以区分直接访问变量和通过属性访问器访问。
如果您尝试在代码中访问str,例如[str length],则代码将无法编译。你需要做[self.str length]或[_str length]。
...因为它是一个NSString不可变属性,所以使用copy
,而不是retain
。
答案 1 :(得分:3)
@synthesize str = _str;
意味着为str
属性合成的实例变量称为_str
。因此,在您的代码中,它与声明的实例变量之间存在不匹配。因此,您实际上最终会得到2个实例变量,一个名为str
,一个名为_str
。
你想这样做:
@interface Foo : NSObject
@property(nonatomic, retain) NSString *str;
@end
@implementation Foo
@synthesize str = _str;
@end
或者这个:
@interface Foo : NSObject {
NSString *str;
}
@property(nonatomic, retain) NSString *str;
@end
@implementation Foo
@synthesize str;
@end
或者显然重命名声明的实例变量_str
。
关于是否使用_
作为前缀(例如 - Prefixing property names with an underscore in Objective C,已经有很多关于SO的问题。
答案 2 :(得分:0)
以下是一个快速示例,说明如何使用名称更改:
@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
如果你没有将str合成为_str,你会在stringTreatment方法中得到一个警告,说明str的本地声明隐藏了实例变量。
另外,在你的代码中,你可以为_str赋值并且有一个外部类调用[MyClass str]并且它会返回它。
因此,长话短说,“str”仍然是您的财产的名称,“_ str”是该财产的内部参考。例如,您将无法使用[MyClass _str],这将无法正常工作。有意义吗?
希望这有帮助。