(目标C)做@synthesize myvar = _myvar(如果有的话)有什么好处?

可能重复:
如何在cocoaObjective-C类中的variables前面加下划线?

我不完全清楚(除了代码的可读性),为什么你要创build一个带有下划线前缀的内部variables,当你创build属性。

由于一切都是在内部处理的,为什么还要这样做呢,因为我们不向getter和setter添加任何代码?

即使我要添加一些代码到getter或setter,我不明白为什么我不能只检查myvar,而不是检查_myvar,然后将其分配给myvar。

任何人都可以给我一些解释,除了“这是因为这是每个人都做?” 我想了解这种做法背后的全部原因(这似乎是相当普遍的,即使没有自定义代码的getter和setter)。

谢谢!

一个Objective-C属性通常有一个支持实例variables(我猜你知道属性和实例variables之间的差异)。

该属性可能与实例variables名称不同。

例如,你可能有一个名为x的实例variables,其属性名为y

您可以使用以下命令将y属性合成到xvariables:

 @synthesize y = x; 

现在关于下划线。

当实例variables的方法参数与实例variables名称相同时,为实例variables使用下划线前缀,以防止命名冲突或编译器警告(阴影variables)是一种常见的做法。

下划线前缀也表明你指的是一个实例variables。

通过为实例variables使用下划线前缀,可以自由使用方法参数,堆栈variables等中不带下划线的名称。

但是在使用属性时,通常不希望用户编写下划线。

所以你通常有一个_x实例variables的x属性。

这就是为什么你写:

 @synthesize x = _x; 

举个例子:

 @interface Test: NSObject { int x; } @property( readonly ) int x; @end 

这是相当普遍的……但现在想象一下在执行:

 - ( id )initWithX: ( int )x {} 

我们有一个命名冲突。

在我们的方法中, x将引用方法的参数。 而且没有很好的方式来访问x实例variables。

根据您的编译器的警告标志,这也可能会产生一个警告( -Wshadow )。

如果您为您的实例variables使用下划线前缀,则一切都很简单:

 - ( id )initWithX: ( int )x { if( ( self = [ super init ] ) ) { _x = x; } return self; } 

没有冲突,没有命名冲突,改进了阅读…只是一个很好的方法…

我自己也好奇这么多次 对其他人的回答感兴趣,但是我发现的一个原因是,当你使用getter / setter时,它会强迫你注意你是否直接访问伊娃。

self.myvar = @"blah";_myvar = @"blah";

VS

self.myvar = @"blah";myvar = @"blah";

离开self.很容易self. 不小心把事故搞糟了,要把事故搞得更加困难。

当使用自己的财产时,很容易忘记“自我”:

 [self.field doSomething]; // what you probably want [self setField:someObject]; // also kosher self.field = someObject; // ditto, although not my style 

 [field doSomething] // might work.. but will bite you eventually field = someObject; // almost certainly wrong anywhere outside a custom setter 

如果财产和伊娃被命名为相同的,那么后一种情况下将毫无怨言地编译并显示出工作…直到他们没有,并且你得到一个奇怪的难以再现的边缘案例错误。

如果伊娃有一个稍微不同的名字,比如用尾部_追加,编译器会阻止你,让你明确地决定:我想直接参考这里的财产,或者伊娃吗?

(所有这些,我很懒,经常做@synthesize field; ,并用@synthesize field = field_;replace它@synthesize field = field_;当我真的需要不同的伊娃时,比如它是自定义设置时间。