Iphone 在目标C中用下划线作为属性名称的前缀

Iphone 在目标C中用下划线作为属性名称的前缀,iphone,objective-c,coding-style,Iphone,Objective C,Coding Style,我以前在变量名中避免使用下划线,这可能是大学Java时代的遗留问题。所以,当我在目标C中定义一个属性时,这是我自然要做的 // In the header @interface Whatever { NSString *myStringProperty } @property (nonatomic, copy) NSString *myStringProperty; // In the implementation @synthesize myStringProperty; 但在几

我以前在变量名中避免使用下划线,这可能是大学Java时代的遗留问题。所以,当我在目标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;
我是否应该克服我对下划线的厌恶,因为这是我应该做的一种方式,有没有一个好的理由让这种风格成为首选呢

更新:现在使用自动属性合成,您可以省去@synthesis,结果与您使用的相同

@synthesize myStringProperty = _myStringProperty;

这清楚地表明了苹果的偏好。从那以后,我学会了停止担忧,喜欢下划线。

这纯粹是一个风格问题


我不知道哪些示例使用带下划线的ivar样式。苹果的官方示例(例如)没有在IVAR前面加上

我总是用下划线。它明确区分了局部变量和实例变量。它还可以避免在以下情况下出现编译器警告:

@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
编辑

在忍受了反对票和阅读了评论之后,让我试着提出我的观点:

苹果公司建议IVAR与其财产同名。苹果还建议属性以小写字母开头。苹果还建议局部变量以小写字母开头

现在你有一个问题了,因为当你读一段代码,看到一个变量被使用时,你不能通过命名约定判断这个变量是ivar还是局部变量。那太糟糕了。解决方案是对IVAR和局部变量使用不同的命名约定。这只是常识

您实现此命名约定的方式无关紧要。如果你真的愿意,你可以简单地在ivar名称后面加上“_WOOHAHA”。我不在乎(但也许其他人会在乎)。问题是,知道自己在做什么的人决定使用IVAR的“下划线前缀”。依我看,他们做出了正确的决定,即使他们自己的公司提出了其他建议。(我所说的开发人员是编写一些主要苹果框架和.NET框架类的人)

归根结底,代码质量比遵守一条愚蠢的规则更重要,而这条规则甚至没有被鼓吹它的人遵守。


关于您所展示的代码的另一句话:永远不要对字符串属性使用retain。您应该使用复制

有关复制/保留属性的详细信息,请参见:


苹果为自己的“私有”方法保留以下划线开头的选择器,其中包括属性。但我不认为他们会保留ivar的名字

就我个人而言,我不会使用下划线来开始任何类型的变量名。这是一个不透明的惯例。如果其他人使用下划线作为局部变量,而不使用下划线作为实例变量,该怎么办?如果您在一个方法中意外地省略了下划线,而该方法中定义了一个同名的局部变量,该怎么办


最好让你的本地名字和你的ivar名字不同。例如,在setter中,您可以使用newName或neWValue。

当前建议的Objective-C2.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 

运行时的KVC部分在找不到检索该变量的消息时,在对象上使用valueForKey:时需要名称或_nameivar。看

如果运行时费心搜索_名称,而苹果文档首先提到了_名称,那么这可能是一个很好的理由。让我们来看看一些SDK类:UnavigigBase.h。这个类在所有Ivar的前面都有下划线,UIVIEW也是…这个名单还有很多。好吧,也许是新的iOS SDK和好的ole NS*类不会这样做。。。错;它们在头文件中也使用下划线

苹果在私有API消息和IVAR中使用下划线。我不明白为什么他们的示例不推动这种行为,特别是当运行时费心将这种所谓的“命名约定”硬编码到变量搜索路径中时。看到一些一致性会很好


请注意,要符合KVC,必须遵循严格的命名方案;上面的链接帮助您遵守这一点,以使用运行时的这一方便功能

我只想指出,使用核心数据的新导航项目默认使用尾随下划线,并将变量设置为私有

@interface MyTestAppDelegate : NSObject <UIApplicationDelegate> {

    UIWindow *window;
    UINavigationController *navigationController;

@private
    NSManagedObjectContext *managedObjectContext_;
    NSManagedObjectModel *managedObjectModel_;
    NSPersistentStoreCoordinator *persistentStoreCoordinator_;
}

@interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {

@private
    NSFetchedResultsController *fetchedResultsController_;
    NSManagedObjectContext *managedObjectContext_;
}
@接口MyTestAppDelegate:NSObject{
UIWindow*窗口;
UINavigationController*导航控制器;
@私人的
NSManagedObjectContext*managedObjectContext_389;;
NSManagedObjectModel*managedObjectModel;
NSPersistentStoreCoordinator*persistentStoreCoordinator;
}
@接口RootViewController:UITableViewController{
@私人的
NSFetchedResultsController*fetchedResultsController;
NSManagedObjectContext*managedObjectContext_389;;
}

在2012-02-16修订版之后,苹果公司在“Cocoa编码指南”中明确规定了前缀为u的实例变量的命名约定及其原因

确保实例变量的名称简洁地描述了属性
@implementation MyClass {
    BOOL _showsTitle;
}
@implementation MyClass
@synthesize showsTitle=_showsTitle;