代码之家  ›  专栏  ›  技术社区  ›  Michael Behan

在目标C中为属性名称加上下划线[重复]

  •  54
  • Michael Behan  · 技术社区  · 16 年前

    我以前避免在变量名中使用下划线,这可能是我大学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;
    

    我是否应该忘记我对下划线的厌恶,因为这是我应该做的一种方式,有没有充分的理由让这种风格成为首选?

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

    @synthesize myStringProperty = _myStringProperty;
    

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

    7 回复  |  直到 12 年前
        1
  •  50
  •   Community Mohan Dere    9 年前

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

    @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名称后面加上“\u WOOHAHA”。我不在乎(但也许其他人会在乎)。问题是,知道自己在做什么的人决定使用IVAR的“下划线前缀”。嗯,他们做出了正确的决定,即使他们自己的公司推荐了其他东西。(我所说的开发人员是编写一些主要苹果框架和.NET框架类的人)

    归根结底,代码质量比遵守一条愚蠢的规则更重要,因为人们甚至没有遵守这条规则。


    关于您显示的代码的另一句话:永远不要使用 保持 关于字符串属性。您应该使用 复制 相反

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

    NSString property: copy or retain?

        2
  •  29
  •   Taka    14 年前

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

    确保实例变量的名称简洁地描述了存储的属性。通常,您不应该直接访问实例变量,而应该使用访问器方法(您可以在init和dealloc方法中直接访问实例变量)。为了有助于表明这一点,请在实例变量名称前面加下划线(\u1),例如:

    @implementation MyClass {
        BOOL _showsTitle;
    }
    

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

    @implementation MyClass
    @synthesize showsTitle=_showsTitle;
    

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

    斯坦福大学的保罗·赫加蒂(PaulHegarty)在2011年秋季在iTunes U、iPhone应用程序开发CS193p上的演讲也解释了这一传统。

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

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

        3
  •  18
  •   Emil    14 年前

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

    不管怎样,由于对象仍然必须向自己发送消息才能访问属性,因此很难混淆您是在访问属性还是在直接访问其后备ivar时,尽管使用2.0 dot访问属性确实使其更为可能。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 
    
        4
  •  6
  •   Dan Rosenstark    14 年前

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

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

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

        5
  •  3
  •   kennytm    16 年前

    这纯粹是一个风格问题。

    我不知道哪些示例使用带下划线的ivar样式。苹果官方示例(例如。 CryptoExercise )不要在IVAR前面加前缀 _ .

        6
  •  2
  •   jon    16 年前

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

    @interface MyTestAppDelegate : NSObject <UIApplicationDelegate> {
    
        UIWindow *window;
        UINavigationController *navigationController;
    
    @private
        NSManagedObjectContext *managedObjectContext_;
        NSManagedObjectModel *managedObjectModel_;
        NSPersistentStoreCoordinator *persistentStoreCoordinator_;
    }
    
    @interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
    
    @private
        NSFetchedResultsController *fetchedResultsController_;
        NSManagedObjectContext *managedObjectContext_;
    }
    
        7
  •  1
  •   Brent Priddy    15 年前

    当在对象上使用valueForKey:on时,运行时的KVC部分需要一个名称或\u name ivar,但它找不到用于检索该变量的消息。看见 http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html

    如果运行时费心搜索\u名称,而apple文档首先提到了\u名称,那么这可能是一个很好的原因。让我们看看一些SDK类:UINavigationBar。这个类在所有IVAR前面都有下划线,UIView也是。。。清单还在继续。好吧,也许新的iOS SDK就是这样,好的ole NS*类不会这样做。。。错误的它们在头文件中也使用下划线。

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

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