合成中的奇怪任务

时间:2012-01-27 16:05:13

标签: objective-c ios

我见过很多像这样的代码

header.h

@interface Foo : NSObject
{
  NSString *str;
}

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

然后在实施中

@implementation Foo
 @synthesize str = _str;
@end

我无法理解使用此类作业有什么好处?

@synthesize str = _str;

3 个答案:

答案 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],这将无法正常工作。有意义吗?

希望这有帮助。