命名规范
命名清晰
- 命名要尽可能简要清晰。在清晰的基础上尽量保持简洁。
- 一般而言,不要简写名称,尽量全拼出来,即使名字会很长。
- 要避免语义不清晰的API命名
一致性
- 在不同的类,不同的方法中,相同作用的方法或者是变量,尽量保持命名的一致性。
前缀
- 前缀需要有一种约定格式。一般由2~3个大写字母组成,不要用下划线或者子前缀。
- 在命名类名,协议名,方法名,常量名或者宏定义结构体,采用统一约定前缀。
书写约定
- 包含多个单词的命名,不要用破折号,下划线,点号等作为命名的一部分或者分隔符。应该采用驼峰样式,第一个单词首字母小写,其它单词首字母大写。
- 避免使用下划线作为前缀来表明是私有方法(实例变量允许使用下划线作为前缀)。下划线作为前缀是苹果持有的规范,被第三方应用有可能会引起冲突。
类和协议的命名
- 类名必须包含一个名字来清晰的标明类的作用
- 名字开头需要有约定的前缀
- 协议的命名必须和他的行为相符。有些协议是类相关的,那名字应该和相关类保持一致;有些协议是和类无关的,那名字应该避免和类名混淆。
头文件
- 如果一个类或一个协议和其他类或协议无关,要单独定义头文件,并且其头文件名称要能够标明其用途。
- 相关类或者相关协议或者类别,可以将他们的声明放在一个头文件中。命名上可以以其中最主要的类名或协议名作为头文件名。
- 每一个framework都应该有一个头文件,以framework名称命名,包含此framework中所有的public头文件。
方法命名
通用约定
- 小写字母开头,名称中包含的单词首字母大写,不要用约定前缀。
- 方法名必须能够自解释当前方法的行为。一般动词开头,避免用do or does作为名字的一部分。另外,不要在动词前面用形容词或副词。
- 如果方法是需要返回接受者的一个属性,名字前面应该是属性名,没有必要用“get”,除非返回值是通过间接方式返回的。
- 方法名称中所有参数之前都应该有关键词说明参数用意。
- 不要用”and”来连接方法中属于接收者属性的关键词。如果方法需要描述两个不同的行为动作,可以用”and”连接他们。
属性方法
属性方法都有着固定的格式:
如果属性用名词来描述,那么格式为
-(type)noun;
-(void)setNoun:(type)aNoun;
比如:
-(NSString *)title; - (void)setTitle:(NSString *)aTitle;
如果属性用形容词来描述,那么格式为:
-(BOOL)isAdjective;
-(void)setAdjective:(BOOL)flag;
比如:
- (BOOL)isEditable; - (void)setEditable:(BOOL)flag;
如果属性用动词来描述,那么格式为:
-(BOOL)verbObject;
-(void)setVerbObject:(BOOL)flag;
比如:
- (BOOL)showsAlpha; - (void)setShowsAlpha:(BOOL)flag;
你可能会用情态动词来阐明方法的意思,比如”can”, “should”, “will”等等,但是不要用“do” or “does”。
- 只在那些需要间接返回对象或值的方法中用”get”。那些被返回多个对象的方法需要用到”get”这种格式。
代理方法
有几种格式:
- 以类的对象名开始,后面跟发送消息的行为;
- 如果方法只有一个参数,类对象名和方法行为名拼接在一起;
- 如果方法是需要接收通知,参数用notification对象;
- 用”did”和”will”来代理即将发生或刚刚发生过的行为;
- 如果是通过代理请求某个对象的行为,建议用”should”。
集合方法
格式如下:
-(void)addElement:(elementType)anObj;
-(void)removeElement:(elementType)anObj;
-(NSArray *)elements;
举例:
- (void)addLayoutManager:(NSLayoutManager *)obj;
- (void)removeLayoutManager:(NSLayoutManager *)boj;
- (NSArray *)layoutManagers;
一些指引:
- 如果集合是不需要排序的,建议用NSSet;
如果是要插入到集合中的某个特定位置,用一下方式:
- (void)insertLayoutManager:(NSLayoutManager *)obj atIndex:(int)index; - (void)removeLayoutManagerAtIndex:(int)index;
集合方法中一些需要谨记的实现细节:
- 这些方法通常意味着拥有插入对象的所有权,所以添加或插入的代码必须retain它们,删除的代码必须release它们。
方法参数
- 方法中的参数,首字母要小写;
- 参数中不要用”pointer” or “ptr”。是不是指针通过类型声明区分而不是通过名字。
- 尽量避免用一个字母或者两个字母来命名参数;
- 尽量避免用名字简写来命名参数;
私有方法
很多情况下,私有方法所遵循的规范和公有方法一样。然而还是有一些规范用来将它们和公有方法区分。在Cocoa中,很多私有方法是以下划线开头的,所以:
- 不要用下划线作为私有方法的前缀;
- 如果你的类是Cocoa中类的子类,你想确保你的方法和父类中的方法不同,可以添加一个属于你自己的前缀,但一定要保证唯一。
属性和数据类型
属性和实例变量命名
如果属性是用名词或者动词表达,格式如下:
@property (…) type nounOrVerb;
比如:
@property (strong) NSString *title; @property (assign) BOOL showsAlpha;
如果属性使用形容词来表达,不需要”is”作为前缀。比如:
@property (assign, getter=isEditable) BOOL editable;
很多情况下,当你使用一个属性的时候,往往还需要合成(synthesize)其对应的实例变量。确保实例变量能够简洁的描述属性变量。通常你不需要直接访问实例变量,而是通过属性方法访问。实例变量一般用下划线作为前缀。比如:
@implementation MyClass {
BOOL _showsTitle;
}
如果你要通过生命的属性来合成实例变量,需要用@synthesize声明。
@implementation MyClass
@synthesize showsTitle=_showsTitle;
当添加一个实例变量到某一个类中时,需要谨记以下几条:
- 避免显式的声明公有的实例变量;
- 如果你需要显示的声明实例变量,通过@private or @protected.
- 如果一个实例变量被用来访问对象的某个属性,确保你已经写了属性方法(如果有可能,用已声明的属性)。
常量
枚举常量
每组枚举常量要有对应数字;
你可以为像位掩码这样的事物创建没有名字的枚举,举例:
enum { NSBorderlessWindowMask = 0, NSTitledWindowMask = 1 << 0, NSClosableWindowMask = 1 << 1, NSMiniaturizableWindowMask = 1 << 2, NSResizableWindowMask = 1 << 3 };
用const创建常量
用const创建float类型的常量,如果常量与其它常量毫无关系,也可以用const来定义整型常量;否则,就用enum。const定义常量格式如下:
const float NSLightGray;
其它类型的常量
- 一般最好不要用#define来定义常量。
通知和异常
通知,一般组成:
[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification
举例:
NSApplicationDidBecomeActiveNotification NSWindowDidMiniaturizeNotification NSTextViewDidChangeSelectionNotification NSColorPanelColorDidChangeNotification
异常,一般组成:
[Prefix] + [UniquePartOfName] + Exception
举例:
NSColorListIOException NSColorListNotEditableException NSDraggingException NSFontUnavailableException NSIllegalSelectorException