为什么在最新版本的
Xcode(dp-4)中使用retain声明变量,非原子使用变量名之前的下划线?这是否会产生某种类型的安全性?
例如,我创建了一个属性:
@property (retain,nonatomic) IBOutlet UILabel *name;
除非我将dealloc中的变量更改为不具有_,否则我必须这样做:
@synthesize name = _name;
为什么是这样?
解决方法
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";
而且,作为一名尽职尽责的程序员,你会包含一个评论,解释你为什么要进行这种不规则的操作.