为什么Xcode会自动使用下划线创建变量?

时间:2013-01-02 00:59:25

标签: objective-c xcode declared-property

为什么在最新版本的Xcode(dp-4)中使用retain,nonatomic声明的变量是在变量名之前使用下划线?这是否会产生某种类型的安全性?

例如,我创建了一个属性:

@property (retain, nonatomic) IBOutlet UILabel *name;

除非我将dealloc内的变量更改为没有_,否则我必须这样做:

@synthesize name = _name;

为什么会这样?

2 个答案:

答案 0 :(得分:7)

Mark Dalrymple,比我更聪明,写了关于这个主题的a blog post at Big Nerd Ranch。底线:下划线是一个好主意。我将在这里总结他的帖子,以防链接在将来停止工作,但如果可能的话,你应该阅读他的帖子而不是我的摘要。

当显式调用@synthesize是强制性的时,他写回了这篇文章。他主张代码如:

// soapbubble.m
@synthesize viscosity = _viscosity;
@synthesize detergentBrand = _detergentBrand;

这些天Xcode自动隐含地包含@synthesize。它使用前置下划线这样做,显然Apple的工程师同意Mark。

他的第一个理由是风格。它允许您轻松查看哪些变量是本地变量,哪些变量是setter中的参数:

- (void) setPonyName: (NSString *) ponyName {
    [_ponyName autorelease];
    _ponyName = [ponyName copy];
}

(这是一个pre-ARC setter,所以现在这个方法完全没必要了,但如果setter做了更多的事情,而不仅仅是释放和分配一个值,那么它仍然适用。)

他的第二个原因(也是我认为更重要的一个原因)是消除了一类很难追查的错误。

此代码:

self.ponyName = @"Mikey";

与:

相同
[self setPonyName: @"Mikey"];

如果没有前置下划线,此代码也有效:

ponyName = @"Mikey";

但它不会调用setter,因此不会发生setter中的任何副作用。同样,在setter除了更改局部变量的值之外还做额外的工作的情况下,这可能会引起很大的麻烦。使用前置下划线,该行将导致编译错误。您必须非常明确地想要设置局部变量:

_ponyName = @"Mikey";

并且,作为尽职尽责的程序员,你会包含一个评论,解释你为什么要进行这种不规则的操作。

答案 1 :(得分:1)

@synthesize name = _name中的

“_ name”只是由Xcode自动创建的变量名。这样做是因为@synthesize只创建了setter和getter,如果你不使用_name,它将获取你的属性名称,即name(在这种情况下),最后导致你的app中的bug。 _name只是一个命名约定。您可以使用任何变量名来代替_name。这样@synthesize将在其实现中使用该变量名。