如何在cocoaObjective-C类中的variables前面加下划线?
我在几个iPhone例子中已经看到,属性在variables前面使用了下划线_。 有谁知道这是什么意思? 或者它是如何工作的?
我正在使用的接口文件如下所示:
@interface MissionCell : UITableViewCell { Mission *_mission; UILabel *_missionName; } @property (nonatomic, retain) UILabel *missionName; - (Mission *)mission;
我不确定到底是什么,但是当我尝试设置任务名称如:
aMission.missionName = missionName;
我得到的错误:
请求成员'missionName'的东西不是一个结构或联盟
如果你为你的ivars使用下划线前缀(这只是一个常用的惯例,但是有用的),那么你需要做一件额外的事情,所以自动生成的访问器(对于属性)知道使用哪个ivar。 具体来说,在你的实现文件中,你的synthesize
应该看起来像这样:
@synthesize missionName = _missionName;
更一般地说,这是:
@synthesize propertyName = _ivarName;
这只是一个可读性的约定,它不会对编译器做任何特殊的事情。 你会看到人们在私有实例variables和方法名称上使用它。 苹果实际上build议不要使用下划线(如果你不小心,你可以重写你的超类中的东西),但是你不应该为忽略这个build议而感到不快。 🙂
我所看到的唯一有用的目的是区分如上所述的局部variables和成员variables,但这不是一个必要的约定。 当与@synthesize missionName = _missionName;
配对时,它会增加合成语句的详细程度 – @synthesize missionName = _missionName;
,到处都是丑陋的。
不要使用下划线,只要在不冲突的方法中使用描述性的variables名。 当它们发生冲突时,方法中的variables名应该是下划线,而不是多个方法可能使用的成员variables 。 唯一常用的地方是setter或init方法。 另外,它会使@synthesize语句更加简洁。
-(void)setMyString:(NSString*)_myString { myString = _myString; }
编辑:使用自动综合的最新编译器function,我现在使用下划线为伊娃(罕见的情况下,我需要使用伊娃来匹配什么自动合成。
这并不意味着什么,这只是一些人用来区分成员variables和局部variables的惯例。
至于这个错误,听起来像一个Mission有错误的types。 它的声明是什么?
这只适用于合成属性的命名约定。
当您在.m文件中合成variables时,Xcode将自动为您提供_variable智能。
有一个下划线不仅可以解决你的ivars而不诉诸使用self.member语法,但它使你的代码更具可读性,因为你知道什么时候variables是伊娃(因为它的下划线前缀)或成员参数(没有下划线)。
例:
- (void) displayImage: (UIImage *) image { if (image != nil) { // Display the passed image... [_imageView setImage: image]; } else { // fall back on the default image... [_imageView setImage: _image]; } }
这似乎是关于self.variableName和_variablename的问题的“主”项。 什么让我一个循环是在.h,我有:
... @interface myClass : parentClass { className *variableName; // Note lack of _ } @property (strong, nonatomic) className *variableName; ...
这导致self.variableName和_variableName是.m中的两个不同的variables。 我需要的是:
... @interface myClass : parentClass { className *_variableName; // Note presence of _ } @property (strong, nonatomic) className *variableName; ...
然后,在类.m中,self.variableName和_variableName是等价的。
我还不清楚的是,为什么很多例子还在工作,即使是艰难的,这也没有完成。
射线
而不是下划线,你可以使用self.variable的名字,或者你可以合成variables来使用variables或出口,而不用下划线。
从其他答案中遗漏的是,使用_variable
可以防止你不注意地键入variable
和访问伊娃,而不是(假定有意的)财产。
编译器会强制你使用self.variable
或_variable
。 使用下划线使得不可能inputvariable
,这减less了程序员的错误。
- (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; }