为什么在最新版本的Xcode(dp-4)中使用retain,nonatomic
声明的变量是在变量名之前使用下划线?这是否会产生某种类型的安全性?
例如,我创建了一个属性:
@property (retain, nonatomic) IBOutlet UILabel *name;
除非我将dealloc
内的变量更改为没有_,否则我必须这样做:
@synthesize name = _name;
为什么会这样?
答案 0 :(得分:7)
当显式调用@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)
“_ name”只是由Xcode自动创建的变量名。这样做是因为@synthesize只创建了setter和getter,如果你不使用_name,它将获取你的属性名称,即name(在这种情况下),最后导致你的app中的bug。 _name只是一个命名约定。您可以使用任何变量名来代替_name。这样@synthesize将在其实现中使用该变量名。