Cocoa Objective-c 类中变量前面的下划线如何工作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/822487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does an underscore in front of a variable in a cocoa objective-c class work?
提问by Atma
I've seen in a few iPhone examples that attributes have used an underscore _ in front of the variable. Does anyone know what this means? Or how it works?
我在一些 iPhone 示例中看到,属性在变量前使用了下划线 _。有谁知道这是什么意思?或者它是如何工作的?
An interface file I'm using looks like:
我正在使用的接口文件如下所示:
@interface MissionCell : UITableViewCell {
Mission *_mission;
UILabel *_missionName;
}
@property (nonatomic, retain) UILabel *missionName;
- (Mission *)mission;
I'm not sure exactly what the above does but when I try to set the mission name like:
我不确定上面到底做了什么,但是当我尝试将任务名称设置为:
aMission.missionName = missionName;
I get the error:
我收到错误:
request for member 'missionName' in something not a structure or union
在不是结构或联合的东西中请求成员“missionName”
采纳答案by Kelan
If you use the underscore prefix for your ivars (which is nothing more than a common convention, but a useful one), then you need to do 1 extra thing so the auto-generated accessor (for the property) knows which ivar to use. Specifically, in your implementation file, your synthesizeshould look like this:
如果您对 ivars 使用下划线前缀(这只不过是一个常见的约定,但很有用),那么您需要做 1 件额外的事情,以便自动生成的访问器(用于属性)知道要使用哪个 ivar。具体来说,在您的实现文件中,您synthesize应该如下所示:
@synthesize missionName = _missionName;
More generically, this is:
更一般地说,这是:
@synthesize propertyName = _ivarName;
回答by Marc Charbonneau
It's just a convention for readability, it doesn't do anything special to the compiler. You'll see people use it on private instance variables and method names. Apple actually recommends not using the underscore (if you're not being careful you could override something in your superclass), but you shouldn't feel bad about ignoring that advice. :)
这只是可读性的约定,它对编译器没有任何特殊作用。你会看到人们在私有实例变量和方法名称上使用它。Apple 实际上建议不要使用下划线(如果您不小心,您可能会覆盖超类中的某些内容),但是您不应该为忽略该建议而感到难过。:)
回答by Peter DeWeese
The only useful purpose I have seen is to differentiate between local variables and member variables as stated above, but it is not a necessary convention. When paired with a @property, it increases verbosity of synthesize statements – @synthesize missionName = _missionName;, and is ugly everywhere.
我看到的唯一有用的目的是如上所述区分局部变量和成员变量,但这不是必要的约定。当与 @property 配对时,它会增加综合语句的冗长 - @synthesize missionName = _missionName;,而且到处都是丑陋的。
Instead of using the underscore, just use descriptive variable names within methods that do not conflict. When they must conflict, the variable name within the method should suffer an underscore, not the member variable that may be used by multiple methods. The only common place this is useful is in a setter or in an init method. In addition, it will make the @synthesize statement more concise.
而不是使用下划线,只需在不冲突的方法中使用描述性变量名称。当它们必须冲突时,方法中的变量名应该带有下划线,而不是可以被多个方法使用的成员变量。唯一有用的地方是在 setter 或 init 方法中。此外,它会使@synthesize 语句更加简洁。
-(void)setMyString:(NSString*)_myString
{
myString = _myString;
}
Edit:With the latest compiler feature of auto-synthesis, I now use underscore for the ivar (on the rare occasion that I need to use an ivar to match what auto-synthesis does.
编辑:使用自动合成的最新编译器功能,我现在对 ivar 使用下划线(在极少数情况下,我需要使用 ivar 来匹配自动合成的功能。
回答by smorgan
It doesn't really mean anything, it's just a convention some people use to differentiate member variables from local variables.
它实际上没有任何意义,它只是一些人用来区分成员变量和局部变量的约定。
As for the error, it sounds like aMission has the wrong type. What it its declaration?
至于错误,听起来像aMission的类型错误。它的声明是什么?
回答by Dipak Narigara
This is only for the naming convention of synthesize properties.
这仅适用于合成属性的命名约定。
When you synthesize variables in the .m file, Xcode will automatically provide you _variable intelligence.
当您在 .m 文件中合成变量时,Xcode 会自动为您提供 _variable 智能。
回答by Jason Fuerstenberg
Having an underscore not only makes it possible to resolve your ivars without resorting to using self.membersyntax but it makes your code more readable since you know when a variable is an ivar (because of its underscore prefix) or a member argument (no underscore).
使用下划线不仅可以在不使用self.member语法的情况下解析您的 ivars,而且可以使您的代码更具可读性,因为您知道变量何时是 ivar(因为它的下划线前缀)或成员参数(无下划线) )。
Example:
例子:
- (void) displayImage: (UIImage *) image {
if (image != nil) {
// Display the passed image...
[_imageView setImage: image];
} else {
// fall back on the default image...
[_imageView setImage: _image];
}
}
回答by RayInNoIL
This seems to be the "master" item for questions about self.variableName vs. _variablename. What threw me for a loop was that in the .h, I had:
这似乎是有关 self.variableName 与 _variablename 问题的“主”项。让我感到循环的是在 .h 中,我有:
...
@interface myClass : parentClass {
className *variableName; // Note lack of _
}
@property (strong, nonatomic) className *variableName;
...
This leads to self.variableName and _variableName being two distinct variables in the .m. What I needed was:
这导致 self.variableName 和 _variableName 成为 .m 中的两个不同变量。我需要的是:
...
@interface myClass : parentClass {
className *_variableName; // Note presence of _
}
@property (strong, nonatomic) className *variableName;
...
Then, in the class' .m, self.variableName and _variableName are equivalent.
然后,在类的 .m 中,self.variableName 和 _variableName 是等价的。
What I'm still not clear on is why many examples still work, even tough this is not done.
我仍然不清楚的是,为什么许多示例仍然有效,即使很难做到这一点。
Ray
射线
回答by SARATH SASI
instead of underscore you can use self.variable name or you can synthesise the variable to use the variable or outlet without underscore .
您可以使用 self.variable name 代替下划线,或者您可以合成变量以使用没有下划线的变量或出口。
回答by pkamb
Missing from the other answers is that using _variableprevents you from absentmindedly typing variableand accessing the ivar rather than the (presumedly intended) property.
其他答案中缺少的是 using_variable可以防止您心不在焉地输入variable和访问 ivar 而不是(假定打算使用的)属性。
The compiler will force you to use either self.variableor _variable. Using underscores makes it impossible to type variable, which reduces programmer errors.
编译器将强制您使用self.variable或_variable。使用下划线使得无法键入variable,从而减少程序员错误。
- (void)fooMethod {
// ERROR - "Use of undeclared identifier 'foo', did you mean '_foo'?"
foo = @1;
// So instead you must specifically choose to use the property or the ivar:
// Property
self.foo = @1;
// Ivar
_foo = @1;
}

