Cocoa编程指南
这是一篇翻译版,英文版来自apple的官方文档:
Coding Guidelines for Cocoa
介绍
Cocoa编程指南介绍
通过公开API开发Cocoa框架,插件,或者其他可执行文件需要一些不同于开发应用程序的方式和约定。开发者是你的产品的主要客户,并且让他们没有对你的编程接口感到困惑是非常重要的。这就是API命名约定派上用场,这会有助于你的接口保持一致和清晰。还有些编程技术对于这个框架来说是比较特殊的或者说更加重要,例如版本控制,二进制兼容性,错误处理和内存管理。本专题包含Cocoa命名规范和推荐的框架编程实践。
文档组织结构
本专题所包含的文章分为两类。第一部分和大部分的模块给出了对编程接口的命名规范。apple在自身的Cocoa框架中也使用这些命名规范。这些关于命名规范的包含如下内容:
1. 代码命名基础
2. 方法的命名
3. 函数的命名
4. 属性和数据类型的命名
5. 可接受的简写和缩写
第二部分(当前只有一个成员)讨论框架开发的各个方面
框架开发的小技巧
代码命名基础
类,方法,函数,常量和其他编程接口的元素经常在面向对象编程软件设计被忽视。该部分介绍了许多在cocoa接口中实现的命名规范。
基本原则
清晰
- 尽量保持清楚和简洁很好,但是命名清晰比简洁更重要。
Code | Commentary |
---|---|
insertObject:atIndex: | 好 |
insert:at: | 不清晰;插入什么?“at”表示什么?atNot clear;what is being inserted?what does “at”signify? |
revmoveObjectAtIndext: | 好 |
removeObject: | 好,因为删除作为参数的对象。 |
remove: | 不明确,删除什么? |
- 通常,不要缩写名字。即使它们很长也要拼写出来。
代 码 | 评 价 |
---|---|
destinationSelection: | 好 |
destSel | 不清晰 |
setBackgroundColor: | 好 |
setBkgColor: | 不清晰 |
你可能认为缩写是众所周知的,但它可能不是,特别是有不同的文化和语言背景开发者遇到你的方法和函数。
- 然而,有少数的缩写确实是通用的并且用了很长时间。可以继续使用,查看Acceptable Abbreviations and Acronyms.
- 避免API命名不明确,例如方法名称可能被解释为多种含义。
代码 | 评论 |
---|---|
sendPort | 是发送端口还是返回端口? |
displayName | 在用户界面中显示一个名字还是返回接受者的标题 ? |
一致性
- 尝试保持在Cocoa编程接口上的命名一致性。如果不确定,请查阅现在的头文件或者之前的参看文件。
- 当一个类中的许多方法有多态性的时候,一致性是非常重要的。这些方法在不同的类中使用同样的名称做同样的操作。
代 码 | 评 论 |
---|---|
|
定义在NSView,NSCell,NSControl. |
|
在许多Cocoa类中有定义 |
也可参照:Method Arguments
不要自我引用
- 命名不应该自我引用
代码 | 评论 |
---|---|
NSString | 可以 |
NSStringObject | 自我引用 |
- 作为掩码的一些常量(可以按位与进行合并),这些常量常量一般不使用这种规则,例如作为通知名称的常量.
代码 | 评论 |
---|---|
NSUnderlineByWordMask | 可以 |
NSTableViewColumnDidMoveNotification | 可以 |
前缀
书写约定
下面有几个简单的命名API的书写规范
- 名字有多个单词组成,不要使用下划线,破折号或者其他符号分割。使用驼峰命名法
对于方法命名,以小写字母开头,后面的单词首字母大写。不要使用前缀。
fileExistsAtPath:isDirectory:
- 函数和常量的命名,对于相关的类使用同样的前缀并且首字母大写以及后边的单词
NSRunAlertPanel
NSCellDisabled
- 避免使用下划线作为前缀
类和协议的命名
类的名称应该包含一个清晰的表达出该类的意义。类名应该有一个前缀。Foundation和许多应用程序框架都是一些案例。例如NSString,NSData,NSScanner,NSApplication …和UIButton。
Protocol 应该根据它所组成的一些行为事件来命名。
- 大多数的协议与包含的一些方法有关系而与某种类没有关系。这种协议应该避免与类名混淆。通常约定用一种动名词(“…ing”)的格式.
代 码 | 评论 |
---|---|
NSLocking | 好 |
NSLock | 差(看起来像一个类名) |
- 一些协议包含许多没有关系的方法(而不是创建很多分离的小的协议)。这些协议与某个类有关系,这个类是这些协议的主要表现。在这种情况下,应该约定将协议和类命名一致。
NSObject协议就是这种类型的协议。
头文件
方法命名
方法的命名也许是编程接口中最普通的元素,因此应该在命名过程中需要特别注意。这部分讨论方法命名的如下几个方面:
基本规则
通常有如下几项规则:
- 小写字母开头,大写包含的英文单词的首字母。不要使用前缀
- 对于表示操作于某个对象的方法,方法的命名以动词开头:
- (void)invokeWithTarget:(id)target;
- (void)selectTabViewItem:(NSTabViewItem *)tabViewItem;
不要使用“do” 或者 “does” 作为名字的一部分因为这些助动词几乎没有任何意义。并且,不要在动词前面使用副词或者形容词。
- 如果某个方法返回调用者的某个属性,直接在属性后面命名就可以。不要使用“get”,除非需要直接返回一个或者多个值。
代码 | 评论 |
---|---|
|
正确 |
|
错误 |
|
错误 |
- 在参数前面使用关键字
代码 | 评价 |
---|---|
|
正确 |
|
错误 |
- 在参数前面描述参数
代码 | 评价 |
---|---|
|
正确 |
|
错误 |
- 当创建一个比继承的方法更加明确的方法的时候,需要添加新的关键字在已经存在的方法后面。
代码 | 评价 |
---|---|
|
NSView, UIView. |
|
NSMatrix, a subclass of NSView |
- 不要使用“and”连接是调用者属性的关键字。
代码 | 评价 |
---|---|
|
正确 |
|
错误 |
- 如果方法有两种不同的行为,使用“and”连接它们。
代码 | 评价 |
---|---|
|
NSWorkspace |
访问器方法
访问器方法是一个设置和读取对象的属性值得方法。根据属性的表达方式拥有某种推荐的方式。
- 一个属性表示一个名词,格式是:
- (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”或者“does”
代码 | 评论 |
---|---|
|
正确 |
|
正确 |
|
正确 |
|
正确 |
|
错误 |
|
错误 |
- 只有在间接返回对象和值的方法中才使用“get”,只有需要返回多个值得的方法菜需要使用这种格式。
代码 | 用处 |
---|---|
|
NSBezierPath. |
代理方法
代理方法是对象能够在其代理中唤醒调用当某种事件发生的时候。它们有一种特殊的形式,这种形式同样适用于一个对象数据源的方法中。
- 以表示发送消息的对象所属类来命名开头
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
该类的名字省略了前缀并且以小写字母开头。
- 冒号在类名后面(对于代理对象来说参数是一个引用)除非方法只有一个参数,这个参数就是消息发送者。
- (BOOL)applicationOpenUntitledFile:(NSApplication *)sender;
- 有一种例外就是消息通知发送的消息。这种情况下,唯一的参数是通知对象。
- (void)windowDidChangeScreen:(NSNotification *)notification;
- 代理方法使用“did”或者“will”通知代理已经发生了或者将要发生什么?
- (void)browserDidScroll:(NSBrowser *)sender;
- (NSUndoManager *)windowWillReturnUndoManager:(NSWindow *)window;
- 尽管代理方法可以使用“did”或者“will”,我们推荐使用“should”。
- (BOOL)windowShouldClose:(id)sender;
集合方法
对于管理着一些对象(每一个对象称为一个元素)的集合对象,对一些方法如下的约定。
- (void)addElement:(elementType)anObj;
- (void)removeElement:(elementType)anObj;
- (NSArray *)elements;
例子:
- (void)addLayoutManager:(NSLayoutManager *)obj;
- (void)removeLayoutManager:(NSLayoutManager *)obj;
- (NSArray *)layoutManagers;
下面是对这个指南的一些限制条件和改进
- 如果集合是无序的,返回一个NSSet,不要返回一个NSArray
- 若需要将对象插入到集合的某个特定位置,使用类似于如下的方法
- (void)insertLayoutManager:(NSLayoutManager *)obj atIndex:(int)index;
- (void)removeLayoutManagerAtIndex:(int)index;
需要记忆的一些集合方法的细节
- 这些方法需要代表与操作对象这件的所属关系,添加或者插入需要持有该对象,删除必须释放该对象。
对于上面的规范有一些自于NSWindow类的集合方法
- (void)addChildWindow:(NSWindow *)childWin ordered:(NSWindowOrderingMode)place;
- (void)removeChildWindow:(NSWindow *)childWin;
- (NSArray *)childWindows;
- (NSWindow *)parentWindow;
- (void)setParentWindow:(NSWindow *)window;
方法参数
私有方法
有两条建议
- 不要使用下划线开头,apple在使用。
- 如果子类化一个Cocoa框架类,可以使用公司或者工程名称作为前缀如“XX_”。如果你的项目为:Byte Flogger,前缀是BF_addObject;
函数命名
函数有些需要遵守的规则
- 函数命名如方法的命名很相像,但是有一些例外需要注意
1.使用在常量和类中使用的前缀
2.在前缀后的首字母大写
- 大部分函数以描述函数意义的动词开头
NSHighlightRect
NSDeallocateObjec
查询属性的函数有更多的一些规则
- 如果函数返回其第一个参数的属性,需要省略动词。
unsigned int NSEventMaskFromType(NSEventType type)
float NSHeight(NSRect aRect)
- 如果通过引用返回其值,使用“get”
const char *NSGetSizeAndAlignment(const char *typePtr, unsigned int *sizep, unsigned int *alignp)
- 如果返回一个boolean值,应该以一个变形的动词开头
BOOL NSDecimalIsNotANumber(const NSDecimal *decimal)
属性和数据类型命名
声明属性和实例变量
如果属性或者实例变量是名字和动词,格式如下:
@property(__)type nounOrVerb;
举例
@property (strong) NSString *title;
@property (assign) BOOL showsAlpha;
如果属性或者变量是形容词,但是需要省略“is”前缀,但是需要详细的约定获取方法,例如:
@property (assgin,getter=isEditable) Bool editable;
许多情况下,当使用一个已经声明的属性也应该合成相应的实例变量。
确保实例变量的名字简洁地描述存储属性。通常你不应该直接访问实例变量。应该通过访问方法来访问。为了有助于标志实例变量,可以使用下划线开头,例如:
@implementation MyClass {
BOOL _showsTitle;
}
如果使用一个已经声明的属性来合成实例变量,在@synthesize语句中详细说明实例变量。
@implementation MyClass
@synthesize showsTitle=_showsTitle;
一些注意事项
- 不要显示的声明一个公开的实例变量
- 如果需要声明一个实例变量,明确声明是@private 或者@protected
- 如果一个实例变量一个可访问的实例属性,确保为这个实例变量编写了访问器方法
常量
常量根据创建方式的不同,规则也不一样。
枚举常量
typedef enum _NSMatrixMode {
NSRadioModeMatrix = 0,
NSHighlightModeMatrix = 1,
NSListModeMatrix = 2,
NSTrackModeMatrix = 3
} NSMatrixMode;
使用const创建常量
使用const的例子
const float NSLightGray;
其他类型的常量
- 通常,不要使用#define预处理器命令来创建常量。
- 使用大写,举例
#ifdef DEBUG
- 注意,编译器定义的宏前后都有两个下划线,举例:
__MACH__
通知和异常
通知和异常的命名也是类似的规则。但是两者都有它们推荐的使用方式。
通知
如果一个类有代理,那么代理会通过事先定义好的代理方法来接受大多数的通知。这些通知名称应该反映相应的代理方法。例如,全局的NSApplication对象的自动注册的代理会接受applicationDidBecomeActive:的消息当app发送一个NSApplicationDidBecomeActiveNotification的通知。
通知使用NSString来表示,使用下面的方式来命名:
[Name of associated class] + [Did | Will] + [UniquePartOfName] + Notification
例如:
NSApplicationDidBecomeActiveNotification
NSWindowDidMiniaturizeNotification
NSTextViewDidChangeSelectionNotification
NSColorPanelColorDidChangeNotification
异常
使用全局的NSString对象来表示异常,命名组成如下:
[Prefix] + [UniquePartOfName] + Exception
Unique 部分应该将单词组成在一块并且大写每一个单词的首字母。下面一些例子:
NSColorListIOException
NSColorListNotEditableException
NSDraggingException
NSFontUnavailableException
NSIllegalSelectorException
可接受的简写和缩写
通常,不应该对接口的名称进行缩写。然而,下面列出的缩写已经被创建或者在过去被使用了很久,因此,可以继续使用。关于缩写有一些其他需要注意的地方:
- 来源于标准C库的一些缩写,例如‘alloc’和‘getc’是被允许的。
- 在参数的命名中可以更加*的使用缩写。
Abbreviation | Meaning and comments |
---|---|
alloc | Allocate |
alt | Alternate |
app | Application. For example, NSApp the global application object. However, “application” is spelled out in delegate methods, notifications, and so on. |
calc | Calculate |
dealloc | Deallocate. |
func | Function. |
horiz | Horizontal. |
info | Information. |
init | Initialize (for methods that initialize new objects). |
int | Integer (in the context of a C int—for an NSInteger value, use integer). |
max | Maximum. |
min | Minimum. |
msg | Message. |
nib | Interface Builder archive. |
pboard | Pasteboard (but only in constants). |
rect | Rectangle. |
Rep | Representation (used in class name such as NSBitmapImageRep). |
temp | Temporary. |
vert | Vertical. |
在计算机产业中使用的缩写和首字母缩略词你可能使用到,下面有些熟知的缩略词:
ASCII
XML
HTML
URL
RTF
HTTP
TIFF
JPG
PNG
GIF
LZW
ROM
RGB
CMYK
MIDI
FTP
对于框架开发者的小技巧
这部分是关于框架开发者的一些建议,略…
上一篇: CSS3之动画animation
下一篇: helloword