为什么在最新版本的Xcode(dp-4)中是使用retain,nonatomic
声明的变量,以在变量名称之前使用下划线?这会产生某种类型的安全吗?
例如,我创建一个属性:
@property (retain, nonatomic) IBOutlet UILabel *name;
除非我将dealloc
内部的变量更改为没有_,否则我必须这样做:
@synthesize name = _name;
为什么这是?
马克·达里姆普(Mark Dalrymple)比我聪明,他在Big Nerd Ranch撰写了一篇博客文章,介绍了这个主题。底线:下划线是个好主意。我将在此处总结他的帖子,以防万一链接在将来停止工作,但是如果可能的话,您应该阅读他的帖子而不是我的摘要。
明确调用@synthesize
是强制性的,他写了这篇文章。他提倡的代码,例如:
// soapbubble.m
@synthesize viscosity = _viscosity;
@synthesize detergentBrand = _detergentBrand;
如今,xcode自动而隐式包括@synthesize
。它使用预先的下划线进行了这样做,因此显然苹果工程师同意Mark。
他的第一个原因是风格。它使您可以轻松查看哪些变量是局部的,哪些是setter中的参数:
- (void) setPonyName: (NSString *) ponyName {
[_ponyName autorelease];
_ponyName = [ponyName copy];
}
(这是一个预先进行的设置程序,因此现在将完全不必要,但是如果设置器所涉及的任何其他内容,而不是简单地发布和分配值仍然适用的值。)
他的第二个原因(我认为更重要的是)是消除可能很难追踪的某些类别的错误。
此代码:
self.ponyName = @"Mikey";
与:
相同[self setPonyName: @"Mikey"];
没有预审长的下划线,此代码也有效:
ponyName = @"Mikey";
,但它不调用设置器,因此不会发生设置器中的任何副作用。同样,在设置器除了更改本地变量的值外还会引起大头痛之外的情况。在预先验证的下划线下,该线将导致编译误差。您必须非常明确地要设置局部变量:
_ponyName = @"Mikey";
,作为良心的程序员,您将包括一个评论,确切地解释了为什么要执行这种不规则的动作。
" _ name"中的@synthesize name = _name,只是Xcode自动创建的变量名称。之所以这样做,是因为@synthesize仅创建固定器和getters,如果您不使用_name,它将以您的属性名称,即名称(在这种情况下)以您的属性名称,并最终导致应用程序中的错误。_名称只是一个命名约定。您可以使用任何变量名来代替_name。因此,@synthesize将在其实现中使用该变量名称。