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

use*_*198 8 objective-c

可能重复:
cocoa objective-c类中变量前面的下划线如何工作?

我不完全清楚(除了代码的可读性之外),为什么要在创建属性时创建带下划线前缀的内部变量.

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

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

任何人都可以给我一些解释,除了"这样做是因为这是每个人都做的事情吗?" 我想了解这种做法背后的全部原因(即使没有getter和setter的自定义代码,这似乎也很常见).

谢谢!

Ken*_*ker 9

我自己多次想知道这件事.对其他人的回答感兴趣,但我发现的一个原因是,当你应该使用getter/setter时,它会强迫你注意你是否直接访问了ivar.

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

VS

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

很容易就self.意外地离开了......出乎意料地把它放进去要困难得多_.


Mac*_*ade 8

Objective-C属性通常有一个支持实例变量(我想你知道属性和实例变量之间的区别).

该属性的名称可能与实例变量的名称不同.

例如,您可能有一个名为的实例变量x,其属性名为y.

您可以使用以下方法将y属性合成到x变量:

@synthesize y = x;
Run Code Online (Sandbox Code Playgroud)

现在关于下划线.

通常的做法是使用下划线前缀作为实例变量,以防止命名冲突或编译器警告(阴影变量),例如具有与实例变量同名的方法参数.

下划线前缀还表明您引用的是实例变量.

通过对实例变量使用下划线前缀,您可以在方法的参数,堆栈变量等中使用不带下划线的名称.

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

所以你通常有x一个_x实例变量的属性.

这就是你写的原因:

@synthesize x = _x;
Run Code Online (Sandbox Code Playgroud)

我们来举个例子:

@interface Test: NSObject
{
    int x;
}

@property( readonly ) int x;

@end
Run Code Online (Sandbox Code Playgroud)

这很常见......但现在想象一下这个实现:

- ( id )initWithX: ( int )x
{}
Run Code Online (Sandbox Code Playgroud)

我们有一个命名冲突.

在我们的方法中,x将引用方法的参数.并且没有很好的方法来访问x实例变量.

根据编译器的警告标志,这也可能会生成警告(-Wshadow).

如果为实例变量使用下划线前缀,一切都很简单:

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

    return self;
}
Run Code Online (Sandbox Code Playgroud)

没有冲突,没有命名冲突,改善阅读......只是一个很好的方式......


归档时间:

查看次数:

1724 次

最近记录:

13 年,9 月 前