可能重复:
How does an underscore in front of a variable in a cocoa objective-c class work?
我注意到在很多参考资料中,我发现很多时候,变量在.h文件中被命名为_variable,然后在.m文件中被@ synthesize为< / p>
@synthesize variable = _variable;
为什么这样做?我错过了什么?
谢谢!
答案 0 :(得分:21)
对此没有达成共识。有些人喜欢使用它来清楚地分离出类变量,而另一个响应者注意到避免与传入的参数名冲突。即使在Apple示例代码中,使用情况也是喜忧参半。
但是,我更倾向于不使用_
前缀,并且有两个强有力的理由:
1)有些人认为_
是“私人”的良好指标。我的看法是,应该在没有setter / getter(属性)的情况下访问NO类局部变量,因此它们都是私有的 - 假设为什么不以更容易阅读和使用自动完成的方式命名它们?编译器可以快速显示参数名称的任何重叠,并通过更周密的参数命名(或内部变量)来避免。
2)(更好的理由) - 如果在XCode中使用“refactor”,内部类var的名称与用于访问它的属性相同,则属性和synthesize语句也将被重命名。如果对前缀为_
的类变量使用重构,则不会更改属性名称 - 只需将合成映射到内部名称。我几乎从不希望名称从属性变化到它公开访问的实际变量。仅此一点就让我永远不想使用_
作为变量前缀,因为能够移动名称只是提高代码清晰度所能做的最有用的事情。
答案 1 :(得分:15)
使用该语法可以更清楚地表明ivar和属性是不同的东西。
要对类外部进行编码,因为它使用了属性,所以没有区别。
对于类本身实现中的代码,它可以使ivar在使用时更清晰。
例如,假设我们有一个NSNumber对象的ivar / property:
@interface MyClass : NSObject {
NSNumber *num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end
@implementation MyClass
@synthesize num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// accidentally set the ivar, num is NOT retained
num = [NSNumber numberWithInteger:2];
}
@end
现在为ivar和属性使用不同的名称:
@interface MyClass : NSObject {
NSNumber *i_num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end
@implementation MyClass
@synthesize num = i_num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// compiler error, there is no ivar named "num"
num = [NSNumber numberWithInteger:2];
// set the ivar, so it needs to be a retained object
i_num = [[NSNumber alloc] initWithInteger:3];
}
@end
答案 2 :(得分:9)
以前的答案缺少这背后的历史。在Objective-C 2.0之前,没有属性。所以你有一个像这样的实例变量的对象:
@interface MyObject: NSObject {
NSArray *myArray;
}
@end
但是你如何从其他对象访问它们?解决方案是制造孵化器和吸气剂。但为了避免混淆,他们会这样做:
@interface MyObject: NSObject {
NSArray *_myArray;
}
- (NSArray *)myArray;
- (void)setMyArray:(NSArray *)myArray;
@end
_
用于清除实例变量_myArray
和方法-myArray
之间的混淆。
答案 3 :(得分:4)
有时人们使用mVarName(C ++),而在Obj-c中,样式似乎是_varName。 你可以遇到的一个问题是,假设你对一个函数的参数是... set:(int)x - 但是 - 你有一个名为x的iVar ......你会让编译器为这样的东西哭泣 - 不是提到它令人困惑。
m,_,有助于显示该类的成员属性。
-(void) set:(int)x
{
x = x; // x is an ivar! heh
}
VS
-(void) set:(int)x
{
_x = x; // ahh I see!
}
答案 4 :(得分:1)
这纯粹是惯例。我认为它很常见,因为当你做一个方法getter调用时这样:
[myObject variable]
您实际上正在调用方法,而不是直接访问变量。前面的_表明你在谈论一个变量。就个人而言,我发现这种语法令人烦恼并且分散注意力。我认为这是不必要的,但你是对的,它确实出现在这里和那里。
答案 5 :(得分:1)
我不想使用'_'前缀,因为Apple确实一直使用它。通过避免使用前缀,我更有信心,当我扩展可可触摸类时,我的ivars不会与Apple碰撞。由于我们无法访问基类的源代码,因此这是我所知道的唯一避免意外重用现有私有ivars的方法。
很像
以“_”开头的方法名称(单个下划线字符)保留供Apple使用。
答案 6 :(得分:0)
我的偏好,在Google之后,只是附加一个下划线并明确合成(即使我重新实现):
@synthesize varName=varName_;
如果我在init...
,dealloc
或访问者之外看到尾随下划线,我知道有些东西可疑。