所以,基于下面的代码,你更喜欢实例/函数变量用哪种命名风格?如果你不在意,那么你是如何处理函数参数遮蔽的?
@interface GridItem : NSObject
{
CGRect _rect;
...
}
@end
-(void) initFromRect:(CGRect)rect
{
_rect = rect;
...
}
干杯!
@interface GridItem : NSObject
{
CGRect _rect;
...
}
@end
-(void) initFromRect:(CGRect)rect
{
_rect = rect;
...
}
干杯!
// EmployeeWindowController.h
#import <AppKit/NSWindowController.h>
@interface EmployeeWindowController : NSWindowController {
@private
// model object this window is presenting
Employee *_employee;
// outlets connected to views in the window
IBOutlet NSTextField *nameField;
IBOutlet NSTextField *titleField;
}
- (id)initWithEmployee:(Employee *)employee;
@property(readwrite, retain) Employee *employee;
@end
// EmployeeWindowController.m
#import "EmployeeWindowController.h"
@implementation EmployeeWindowController
@synthesize employee = _employee;
- (id)initWithEmployee:(Employee *)employee {
if (self = [super initWithWindowNibName:@"Employee"]) {
_employee = [employee retain];
}
return self;
}
- (void)dealloc {
[_employee release];
[super dealloc];
}
- (void)windowDidLoad {
// populates the window's controls, not necessary if using bindings
[nameField setStringValue:self.employee.name];
[titleField setStringValue:self.employee.title];
}
@end
你会发现我在-init
和-dealloc
方法中直接引用了一个引用Employee
的实例变量,而在其他方法中使用了属性。 对于属性来说,这通常是一个很好的模式:只在初始化器、-dealloc
方法以及属性的getter和setter中操作属性的底层实例变量。
我遵循Chris Hanson的建议,在ivar前缀方面使用下划线,但我承认我也会在IBOutlets中使用下划线。然而,最近我开始将我的IBOutlet
声明移动到@property
行,按照@mmalc的建议。好处是所有我的ivar现在都有一个下划线,标准的KVC设置器被调用(即setNameField:
)。此外,Interface Builder中的outlet名称没有下划线。
@interface EmployeeWindowController : NSWindowController {
@private
// model object this window is presenting
Employee *_employee;
// outlets connected to views in the window
NSTextField *_nameField;
NSTextField *_titleField;
}
- (id)initWithEmployee:(Employee *)employee;
@property(readwrite, retain) Employee *employee;
@property(nonatomic, retain) IBOutlet NSTextField *nameField;
@property(nonatomic, retain) IBOutlet NSTextField *titleField;
@end
@synthesize foo = _foo;
这告诉编译器使用_foo实例变量来合成foo属性。
如果您编写自己的访问器,那么在实现中只需使用下划线ivar并保留非下划线方法名称即可。
个人而言,我遵循Cocoa命名规范,对于函数和变量使用驼峰命名法,对于对象名称使用大写的驼峰命名法(当然没有前缀NS)。
我发现类型前缀会使代码对于未编写它的人更加不透明(因为每个人都不可避免地使用不同的前缀),而在现代IDE中,很容易确定某些东西的类型,所以我不使用类型前缀。
随着属性的引入,我认为没有必要给类实例变量加上前缀“_”。您可以设置一个简单的规则(在头文件中描述),即任何要从类外部访问的变量必须通过属性访问,或者使用自定义方法来影响值。对我来说,这比在变量前面加上“_”名称要干净得多。它还可以适当地封装值,以便您可以控制它们如何更改。
虽然我喜欢在实例变量前使用下划线前缀,但我讨厌编写@synthesize
行,因为它会导致很多重复(这不是很DRY)。我创建了一个宏来帮助解决这个问题并减少代码重复。因此,现在可以这样写:
@synthesize employee = _employee;
ddsynthesize(employee);
这是一个简单的宏,使用标记粘贴将下划线添加到右侧:
#define ddsynthesize(_X_) @synthesize _X_ = _##_X_
我的编程风格是混合的,实际上是PowerPlant时代的遗留物:
我最常用的前缀是“in”和“out”,用于函数/方法参数。这有助于您一眼了解参数的用途,并且真正有助于防止方法参数与实例变量之间的冲突(您有多少次看到参数“table”与同名的实例变量发生冲突)。例如:
- (void)doSomethingWith:(id)inSomeObject error:(NSError **)outError;
然后我在实例变量和属性名称中使用裸名:
然后我在本地变量前面加上“the”:theTable,theURL等。这有助于区分本地变量和实例变量。
然后按照PowerPlant的样式,我使用了一些其他前缀:k表示常量,E表示枚举,g表示全局变量,s表示静态变量。
我已经使用这种风格大约12年了。
我不喜欢使用下划线作为任何标识符的前缀,因为C和C++都将某些下划线前缀保留供实现使用。
我认为使用"self.variable"很丑陋。
通常情况下,我使用未装饰的标识符(即没有前缀也没有后缀)作为实例变量。如果你的类太复杂以至于无法记住实例变量,那么你就有麻烦了。所以对于你的示例,我会使用"rect"作为实例变量的名称,"newRect"或"aRect"作为参数名称。
Andrew: 实际上有很多Cocoa开发者根本不使用实例变量前缀。在Smalltalk世界中,这也是非常普遍的(事实上,我会说在Smalltalk中几乎没有人在实例变量上使用前缀)。
对于实例变量的前缀,它总是让我想起C++,然后被带到Java和C#中。由于Objective-C世界与C++世界大致平行,而Java和C#世界则是其继承者,这就解释了你可能在不同开发者之间看到的“文化”差异。