iPhone ivar naming convention
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
我注意到,在很多参考资料中,我看到很多时候,变量在.h文件中被命名为变量,然后在.m文件中被@synthesis'd命名为
1 | @synthesize variable = _variable; |
为什么要这样做?我错过了什么?
谢谢!
对此没有达成共识。有些人为了清晰起见喜欢使用它来分离类变量,正如另一个响应者注意到的那样,这样可以避免与传入的参数名冲突。即使在苹果示例代码中,使用也是混合的。
但是,我非常喜欢不使用
1)有些人认为
2)(更好的理由)-如果在Xcode中对内部类var使用"refactor",该内部类var与用于访问它的属性同名,则该属性和synthesis语句也将被重命名。如果在前缀为
使用该语法是一个选项,可以更清楚地说明ivar和属性是不同的。
对于类外部的代码,没有区别,因为它使用属性。
对于类本身实现中的代码,当使用ivar与属性进行比较时,可以更清楚地说明这一点。
例如,假设我们有一个nsnumber对象的ivar/属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @interface MyClass : NSObject { NSNumber *num; } @property (nonatomic, retain) NSNumber *num; - (void)doSomething; @end @implementation MyClass @synthesize num; - (void)doSomething { // set the property, num is properly retained self.num = [NSNumber numberWithInteger:1]; // accidentally set the ivar, num is NOT retained num = [NSNumber numberWithInteger:2]; } @end |
现在对ivar和属性使用不同的名称:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @interface MyClass : NSObject { NSNumber *i_num; } @property (nonatomic, retain) NSNumber *num; - (void)doSomething; @end @implementation MyClass @synthesize num = i_num; - (void)doSomething { // set the property, num is properly retained self.num = [NSNumber numberWithInteger:1]; // compiler error, there is no ivar named"num" num = [NSNumber numberWithInteger:2]; // set the ivar, so it needs to be a retained object i_num = [[NSNumber alloc] initWithInteger:3]; } @end |
以前的答案缺少这背后的历史。在目标C 2.0之前,没有任何特性。所以你会得到一个具有如下实例变量的对象:
1 2 3 4 5 | @interface MyObject: NSObject { NSArray *myArray; } @end |
但是您如何从其他对象访问它们呢?解决办法是制作setter和getter。但为了避免混淆,他们会这样做:
1 2 3 4 5 6 7 8 | @interface MyObject: NSObject { NSArray *_myArray; } - (NSArray *)myArray; - (void)setMyArray:(NSArray *)myArray; @end |
有时人们使用MVARNEX(C++),而在Obj-C中,样式看起来是VALNEX。你能遇到的一个问题是,假设你对一个函数的参数是……set:(int)x-但是-你有一个名为x的ivar…好吧,你会让编译器为这样的事情大哭一场-更不用说它的混乱了。
m,u,无论什么都有助于显示类的成员属性。
1 2 3 4 | -(void) set:(int)x { x = x; // x is an ivar! heh } |
VS
1 2 3 4 | -(void) set:(int)x { _x = x; // ahh I see! } |
我不喜欢使用前缀,因为苹果一直使用它。通过避免使用前缀,我就有了更大的信心,当我扩展CocoaTouch类时,我的ivar不会与苹果的冲突。因为我们不能访问基类的源代码,所以这是我所知道的避免意外重用现有私有IVAR的唯一方法。
很像
Method names beginning with"_", a single underscore character, are reserved for use by Apple.
这纯粹是惯例。我认为这很常见,因为当您进行这样的方法getter调用时:
1 | [myObject variable] |
您实际上是在调用一个方法,而不是直接访问一个变量。前面的uu清楚地表明你在谈论一个变量。就我个人而言,我觉得这种句法很烦人,而且让人分心。我觉得这是不必要的,但你是对的,它确实出现在这里和那里。
我的偏好是,在google之后,只需添加下划线并显式合成(即使我正在重新实现):
1 | @synthesize varName=varName_; |
如果我看到