在cocoa objective-c类中变量前面的下划线如何工作?

时间:2009-05-04 22:48:21

标签: objective-c cocoa-touch cocoa variables syntax

我在一些iPhone示例中看到属性在变量前面使用了下划线_。有谁知道这意味着什么?或者它是如何工作的?

我正在使用的接口文件如下:

@interface MissionCell : UITableViewCell {
    Mission *_mission;
    UILabel *_missionName;
}

@property (nonatomic, retain) UILabel *missionName;

- (Mission *)mission;

我不确定以上是做什么的,但是当我尝试将任务名称设置为:

aMission.missionName = missionName;

我收到错误:

  

请求成员'missionName'不是结构或联合

9 个答案:

答案 0 :(得分:96)

如果你的ivars使用下划线前缀(这只是一个常见的约定,但是很有用),那么你需要做一件额外的事情,以便自动生成的访问器(对于属性)知道哪个ivar使用。具体来说,在您的实施文件中,您的synthesize应如下所示:

@synthesize missionName = _missionName;

更一般地说,这是:

@synthesize propertyName = _ivarName;

答案 1 :(得分:18)

这只是一个可读性约定,它对编译器没有任何特殊之处。您会看到人们在私有实例变量和方法名称上使用它。 Apple实际上建议不要使用下划线(如果你不小心你可以覆盖你的超类中的某些东西),但你不应该对忽略这个建议感到不好。 :)

答案 2 :(得分:9)

我看到的唯一有用的目的是区分局部变量和成员变量,如上所述,但它不是必要的约定。当与@property配对时,它会增加综合语句的详细程度 - @synthesize missionName = _missionName;,并且到处都是丑陋的。

不要使用下划线,只需在不冲突的方法中使用描述性变量名称。当它们必须冲突时,方法中的变量名称应该使用下划线,而不是多个方法可能使用的成员变量。唯一有用的常见地方是setter或init方法。另外,它会使@synthesize语句更简洁。

-(void)setMyString:(NSString*)_myString
{
    myString = _myString;
}

修改 利用自动合成的最新编译器功能,我现在在ivar中使用下划线(在极少数情况下我需要使用ivar来匹配自动合成的功能。

答案 3 :(得分:5)

这并不意味着什么,它只是一些人用来区分成员变量和局部变量的惯例。

至于错误,听起来像是一个错误的类型。它的声明是什么?

答案 4 :(得分:2)

这仅适用于合成属性的命名约定。

当您在.m文件中合成变量时,Xcode会自动为您提供_variable intelligence。

答案 5 :(得分:1)

使用下划线不仅可以解析您的ivars而无需使用 self.member 语法,但它使您的代码更具可读性,因为您知道变量何时是ivar(因为它下划线前缀)或成员参数(无下划线)。

示例:

- (void) displayImage: (UIImage *) image {

    if (image != nil) {
        // Display the passed image...
        [_imageView setImage: image];
    } else {
        // fall back on the default image...
        [_imageView setImage: _image];
    }
}

答案 6 :(得分:1)

这似乎是关于self.variableName与_variablename的问题的“主”项。让我感到厌恶的是那个.h,我有:

...
@interface myClass : parentClass {
className *variableName;    // Note lack of _
}

@property (strong, nonatomic) className  *variableName;
...

这导致self.variableName和_variableName是.m中的两个不同变量。我需要的是:

...
@interface myClass : parentClass {
className *_variableName;    // Note presence of _
}

@property (strong, nonatomic) className  *variableName;
...

然后,在类'.m中,self.variableName和_variableName是等价的。

我还不清楚的是,为什么许多例子仍然有效,即使这样做也很困难。

答案 7 :(得分:0)

而不是下划线,您可以使用self.variable名称,或者您可以合成变量以使用变量或出口而不用下划线。

答案 8 :(得分:0)

其他答案中缺少的是,使用// compare two sequences and produce a third one // having true for positions where both sequences // have equal elements std::transform(seq1.begin(), seq1.end(), seq2.begin(), std::inserter(resul), std::equal_to<>()); 可以防止您无意中输入_variable并访问ivar而不是(假定的)属性。

编译器会强制您使用variableself.variable。使用下划线使得无法键入_variable,从而减​​少程序员错误。

variable