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

我以前避免在我的variables名称下划线,也许是从我的大学Java日子的搁置。 所以当我在Objective C中定义一个属性时,这是我自然而然做到的。

// In the header @interface Whatever { NSString *myStringProperty } @property (nonatomic, copy) NSString *myStringProperty; // In the implementation @synthesize myStringProperty; 

但几乎在每个例子中,它都是这样做的

 // In the header @interface Whatever { NSString *_myStringProperty } @property (nonatomic, copy) NSString *myStringProperty; // In the implementation @synthesize myStringProperty = _myStringProperty; 

我是否应该避免对下划线的厌恶,因为这是它应该完成的一个方法,是否有这样的风格是首选的一个很好的理由?

更新:如今,有了自动属性综合,你可以省去@synthesize,结果和你用过的一样

 @synthesize myStringProperty = _myStringProperty; 

这清楚地显示了你的苹果的偏好。 从那以后,我学会了不再担心和爱下划线。

我总是使用下划线。 它创build了局部variables和实例variables之间的明显区别。 它也避免了在下列情况下的编译器警告:

 @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 

编辑

在忍受下来并阅读评论之后,让我试着指出:

苹果build议ivars与他们的财产具有相同的名称。 苹果还build议,属性以小写字母开头。 苹果还build议本地variables以小写字母开头。

现在你有一个问题,因为当你阅读一段代码,并且你看到一个正在使用的variables时,你不能通过命名约定来判断这个variables是一个伊娃还是一个局部variables。 这很糟糕。 解决scheme是对ivars和局部variables有不同的命名约定。 这只是普通的常识。

你实现这个命名约定的方式是不相关的。 如果你真的想要,你可以简单地追加“_WOOHAHA”伊娃的名字。 我不在乎(但也许别人会)。 事情是那些知道自己在做什么的人已经决定为ivars使用“下划线前缀”。 恕我直言,他们做出了正确的决定,即使他们自己的公司推荐别的东西。 (我所说的开发人员是编写一些主要的Apple框架和.NET框架类的人)

最终,代码的质量比遵循一条愚蠢的规则更重要。


关于你已经显示的代码的另一个评论:从不使用保留string属性。 你应该使用复制

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

NSString属性:复制或保留?

以“_”为前缀的实例variables的命名约定现在已经在2012-02-16修订版之后,由苹果在“cocoa编码指南”中清楚地陈述,其原因如下。

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

 @implementation MyClass { BOOL _showsTitle; } 

如果使用声明的属性综合实例variables,请在@synthesize语句中指定实例variables的名称。

 @implementation MyClass @synthesize showsTitle=_showsTitle; 

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

斯坦福大学Paul Hegarty教授的iTunes U讲座2011年秋季iPhone应用开发讲座也解释了这个约定。

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

我很早就知道这个问题,但是我自己也有同样的问题,想分享一下我的发现。

目前build议Objective-C 2.0的做法是使用与财产相同的名称作为ivar。 您可以select在@property声明中分配一个不同的ivar,但默认情况下,属性的合成访问器将访问与该属性相同名称的ivar,这表明他们期望您遵循的模式。

无论如何,由于对象仍然需要向自己发送消息才能访问属性,所以在访问属性时或直接访问其后援时,很难混淆,尽pipe使用属性的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 

苹果公司保留以下划线开头的select器,用于他们自己的“私人”方法,并包括属性。 尽pipe我不认为他们保留了伊娃的名字。

就个人而言,我会避免使用下划线开始任何types的variables名称。 这是一个不透明的惯例。 如果其他人使用下划线为本地人,没有下划线的实例variables? 如果您不小心在某个方法中忽略了下划线,那么您有一个同名的本地定义?

使您的本地名称与您的伊娃尔名称不同。 例如在一个setter中,你可以使用newName或者neWValue。

这完全是一个风格问题。

我不知道哪些例子使用强调的伊娃风格。 官方的苹果示例(例如CryptoExercise )不会在_加ivars。

我只想指出,使用核心数据的新导航项目默认使用尾部下划线,并使variables保持私密。

 @interface MyTestAppDelegate : NSObject <UIApplicationDelegate> { UIWindow *window; UINavigationController *navigationController; @private NSManagedObjectContext *managedObjectContext_; NSManagedObjectModel *managedObjectModel_; NSPersistentStoreCoordinator *persistentStoreCoordinator_; } @interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> { @private NSFetchedResultsController *fetchedResultsController_; NSManagedObjectContext *managedObjectContext_; } 

运行时的KVC部分在使用valueForKey时需要一个名称或_name ivar:当它无法find消息来检索该variables时。 请参阅http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html

如果运行时困扰search_name,并且苹果文档首先提到_name,那么可能有一个很好的理由。 让我们来看看一些SDK类:UINavigationBar.h这个类在所有的ivars前面都有下划线,UIView也在…列表继续。 也许这是新的Favoury iOS SDK的方式,好的NS *类不会做这样的稀释…错误; 它们也在头文件中使用下划线。

苹果在私有API消息中使用下划线以及ivars。 我不明白为什么他们的例子不会推动这种行为,特别是当运行时不希望将这种所谓的“命名约定”硬编码到variablessearchpath中时。 看到一些一致性会很高兴。

请注意,有一个严格的命名scheme,你必须遵循KVC标准; 上面的链接可以帮助你符合这个使用这个方便的运行时function。