在Objective C中使用下划线前缀属性名称

Mic*_*han 55 iphone coding-style objective-c

我以前在变量名称中避免使用下划线,这可能是我大学Java时代的延续.因此,当我在Objective C中定义一个属性时,这就是我自然而然的事情.

// In the header
@interface Whatever
{
    NSString *myStringProperty
}

@property (nonatomic, copy) NSString *myStringProperty;

// In the implementation
@synthesize myStringProperty;
Run Code Online (Sandbox Code Playgroud)

但在几乎所有的例子中都是如此

// In the header
@interface Whatever
{
    NSString *_myStringProperty
}

@property (nonatomic, copy) NSString *myStringProperty;

// In the implementation
@synthesize myStringProperty = _myStringProperty;
Run Code Online (Sandbox Code Playgroud)

我应该克服对下划线的厌恶,因为这是应该做的一种方式,这种风格是否是一个很好的理由?

更新:现在使用自动属性合成你可以省略@synthesize,结果和你使用的一样

@synthesize myStringProperty = _myStringProperty;
Run Code Online (Sandbox Code Playgroud)

这清楚地表明了Apple的偏好.我已经学会了停止担忧并且喜欢下划线.

Phi*_*ert 47

我总是使用下划线.它在局部变量和实例变量之间创建了明确的区别.在以下情况下,它还可以避免编译器警告:

@interface MyClass
{
    NSString *name
}

@property (nonatomic, copy) NSString *name;

- (id) initWithName:(NSString *) name;
@end

@implementation MyClass

@synthesize name;

// The following method will result in a compiler warning
// (parameter name same as ivar name)
- (id) initWithName:(NSString *) name {
   if (self = [super init]) {
      self.name = name;
   }

   return self;
}

@end
Run Code Online (Sandbox Code Playgroud)

编辑:

在不得不忍受赞成票并阅读评论之后,让我试着指出我的观点:

Apple建议ivars与其属性具有相同的名称.Apple还建议属性以小写字母开头.Apple还建议局部变量以小写字母开头.

现在你遇到了一个问题,因为当你读取一段代码并且看到一个正在使用的变量时,如果这个变量是一个ivar或一个局部变量,你就无法通过命名约定来告诉你.太糟糕了.解决方案是对ivars和局部变量使用不同的命名约定.这只是普通的常识.

实现此命名约定的方式无关紧要.如果你真的想要,你可以简单地将"_WOOHAHA"附加到ivar名称.我不在乎(但也许其他人会).问题是知道他们正在做什么的人决定使用ivars的"下划线前缀".恕我直言,他们做出了正确的决定,即使他们自己的公司推荐别的东西.(我正在谈论的开发人员是编写一些主要的Apple框架和.NET Framework类的人)

最后,代码质量比遵循一个愚蠢的规则更重要,而这个规则甚至没有人们传播它.


关于你所展示的代码的另一个评论:永远不要在字符串属性上使用retain.你应该使用复制.

有关复制/保留属性的更多信息,请参阅:

NSString属性:复制还是保留?

  • 这不是那个.这是关于命名约定.当您看到使用带有下划线前缀的变量的代码时,您立即知道它是一个ivar,而不是一个局部变量.Apple就是这样做的,微软在完整的.NET框架代码中使用了这个约定. (5认同)
  • 我没有说这是一个标准.我说"我总是使用下划线,因为......".我已经与苹果和微软宣传有缺陷的编码实践.他们告诉我们以某种方式做事,但对于他们自己的代码,他们使用不同的(更好的)标准.任何能够减少混淆并更好地理解/读取代码的编码实践都是正确的选择. (4认同)
  • 哦,顺便说一句,*我*知道我在做什么,我不使用下划线前缀.此外,苹果工程师确实知道他们在做什么只是因为他们是Apple,这是一个不安全的假设. (2认同)

Tak*_*aka 29

现在,在2012-02-16修订版之后,Apple在"可可编码指南"中明确说明了以_为前缀的实例变量的命名约定.

确保实例变量的名称简明地描述了存储的属性.通常,您不应该直接访问实例变量,而应该使用访问器方法(您可以直接在init和dealloc方法中访问实例变量).为了帮助发出信号,请使用下划线(_)作为实例变量名称的前缀,例如:

@implementation MyClass {
    BOOL _showsTitle;
}
Run Code Online (Sandbox Code Playgroud)

如果使用声明的属性合成实例变量,请在@synthesize语句中指定实例变量的名称.

@implementation MyClass
@synthesize showsTitle=_showsTitle;
Run Code Online (Sandbox Code Playgroud)

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE

2011年秋季由斯坦福大学Paul Hegarty教授的iTunes U,iPhone App Development CS193p讲座也解释了这一惯例.

http://itunes.apple.com/itunes-u/ipad-iphone-application-development/id473757255

我知道很久以前就问过这个问题了,但我自己也有同样的问题想分享我的发现.


小智 18

目前建议的Objective-C 2.0实践是使用与ivar相同的名称作为属性.您可以选择在@property声明中指定不同的ivar,但默认情况下,属性的合成访问器将访问与该属性同名的ivar,这表明它们是您希望遵循的模式.

无论如何,由于对象仍然必须向自己发送消息以访问属性,因此当您访问属性或直接访问其支持ivar时很难混淆,尽管使用2.0点访问属性确实使其成为可能更有可能.使用标准消息传递语法使意图更明确,IMO.

@interface Foo : NSObject {
     NSNumber *bar;
} 
@property(readwrite, retain) NSNumber * bar
@end

@implementation Foo 
@synthesize bar;

-(void) baz {
   NSNumber *numberOne = [NSNumber numberWithInt: 1];   
   //Both set the value of bar through either the your custom or the synthesized setter method
   [self setBar:numberOne];  
   self.bar = numberOne; 

   //Both get the value of bar through your synthesized or your custom accessor method
   NSNumber *fooBar = [self bar];
   fooBar = self.bar;

   //Both manipulate the bar ivar directly
   bar = numberOne;
   fooBar = bar;
}
@end 
Run Code Online (Sandbox Code Playgroud)


Jer*_*myP 6

Apple保留选择器以下划线开头,用于他们自己的"私人"方法,其中包括属性.我不认为他们保留了伊娃的名字.

就个人而言,我会避免使用下划线来启动任何类型的变量名称.这是一个不透明的惯例.如果其他人对本地人使用下划线而对实例变量没有下划线怎么办?如果您在具有相同名称的本地定义的方法中意外省略了下划线,该怎么办?

使您的本地名称与您的ivar名称不同更好.例如,在setter中,您可以使用newName或neWValue.


ken*_*ytm 3

这纯粹是一个风格问题。

我不知道哪些例子使用了下划线的ivar风格。Apple 官方示例(例如CryptoExercise)没有在 ivars 中添加前缀_

  • 检查 UIKit 的任何 UI*.h 文件。它们都使用下划线前缀来表示私有 ivars。 (2认同)
  • @Philippe:这些类中的 ivar **不应该使用**。哎呀,苹果甚至在内部使用私有 API。关键是给第三方开发人员的示例从不使用前导“_”。 (2认同)