2012-01-27 68 views
1

我已经看到了很多这样的代码奇怪的分配

header.h

@interface Foo : NSObject 
{ 
    NSString *str; 
} 

@property(nonatomic, retain) NSString *str; 
@end 

,然后在执行

@implementation Foo 
@synthesize str = _str; 
@end 

我不明白什么好处使用这种转让?

@synthesize str = _str; 
+0

[在Objective C中用下划线前缀属性名称](http://stackoverflow.com/questions/3521254/prefixing-property-names-with-an-underscore-in-objective-c) – 2012-01-27 16:14:17

+0

BTW请务必阅读最受赞誉的答案,而不仅仅是被接受的答案。 – 2012-01-27 16:14:47

回答

3

这只是一个常见的命名约定。

在您的实现中,您可以区分直接访问通过属性访问器访问变量。

如果您尝试访问代码中的str,例如[str length],代码将无法编译。您需要执行[self.str length]或[_str length]。

...因为它是一个NSString不变的属性,所以使用copy而不是retain

+1

您可以使用与可变性无关的保留...。 – 2012-01-27 16:22:51

+1

@GradyPlayer保留对于具有可变子类的对象来说不是一个好主意,因为可变对象可以在您不知情的情况下进行更改。它更安全地使用复制 – wattson12 2012-01-27 16:52:15

+0

@GradyPlayer http://stackoverflow.com/questions/387959/nsstring-property-copy-or-retain – bandejapaisa 2012-01-29 09:50:30

3

@synthesize str = _str;将意味着为str属性合成的实例变量称为_str。因此,在你的代码中,它与声明的实例变量之间存在不匹配。所以你最终会得到两个实例变量,一个名为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)作为前缀,有很多问题。

0

下面是如何可以使用名称变更有用一个简单的例子:如果你不会合成str作为_STR

@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 

,你会得到在stringTreatment方法警告说, str的局部声明隐藏实例变量。

另外,在你的代码中,你可以给_str赋值并且有一个外部类调用[MyClass str],它会返回它。

因此,长话短说,“str”仍然是您的财产的名称,“_str”是该财产的内部参考。例如,你将无法使用[MyClass _str],这是行不通的。说得通?

希望这会有所帮助。