一.代码命名
一般性原则
最好是既清晰又简短,但不要为简短而丧失清晰性。
例如:removeObject:AtIndex:good
remove不清晰;要移除什么?
名称通常不缩写,即使名称很长,也要拼写完全。
例如:setBackgroundColor:good
setBgColor:不清晰
方法命名
1.一般性规则
小写第一个单词的首字母,大写随后单词的首字母,不使用前缀。
有两种例外情况:1,方法名以广为人知的大写字母缩略词(如PDF)开头;2,私有方法可以使用统一的前缀来分组和辨识。
表示对象行为的方法,名称以动词开头:
-(void)removeAllObjects;
名称中不要出现do或does,因为这些助动词没什么实际意义。也不要在动词前使用副词或形容词修饰。
如果方法返回方法接收者的某个属性,直接用属性名称命名。不要使用get,除非是间接返回一个或多个值。
例如:-(NSSize)cellSize;对
- (NSSize)getCellSize;错
参数要用描述该参数的关键字命名
-(void)sendAction:(SEL)aSelector to:(id)anObject
forAllCells:(BOOL)flag;对
-
(void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag;错
参数前面的单词要能描述该参数。
-(id)viewWithTag:(int)aTag;对
-(id)taggedView:(int)aTag;错
不要使用and来连接用属性作参数关键字
- (int)runModalForDirectory:(NSString *)pathfile:(NSString *)name types:(NSArray *)fileTypes;对
- (int)runModalForDirectory:(NSString *)pathandFile:(NSString *)name andTypes:(NSArray *)fileTypes;错
如果方法描述两种独立的行为,使用and来串接它们
- (BOOL)openFile:(NSString *)fullPathwithApplication:(NSString *)appName andDeactivate:(BOOL)flag;
2.访问方法
访问方法是对象属性的读取与设置方法。其命名有特定的格式依赖于属性的描述内容。
如果属性是用名词描述的,则命名格式为:
-(type)noun;
-(void)setNoun:(type)aNoun;
如果属性是用形容词描述的,则命名格式为:
-(BOOL)isAdjective;
-(void)setAdjective:(BOOL)flag;
如果属性是用动词描述的,则命名格式为:(动词要用现在时时态)
-(BOOL)verbObject;
-(void)setVerbObject:(BOOL)flag;
不要使用动词的过去分词形式作形容词使用
-(void)setAcceptsGlyphInfo:(BOOL)flag;Right
-(BOOL)acceptsGlyphInfo;Right
-(void)setGlyphInfoAccepted:(BOOL)flag;Wrong
-(BOOL)glyphInfoAccepted;Wrong
可以使用情态动词(can,
should, will等)来提高清晰性,但不要使用do或does。
只有在方法需要间接返回多个值的情况下,才使用get
-(void)getLineDash:(float *)pattern count:(int *)count phase:(float *)phase;
3.委托方法
委托方法是那些在特定事件发生时可被对象调用,并声明在对象的委托类中的方法。它们有独特的命名约定,这些命名约定同样也适用于对象的数据源方法。
名称以标示发送消息的对象的类名开头,省略类名的前缀并小写类第一个字符
-(BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(int)row;
冒号紧跟在类名之后(随后的那个参数表示委派的对象)。该规则不适用于只有一个sender参数的方法,也不适用于响应通知的方法,在这种情况下,方法的唯一参数表示通知对象。
用于通知委托对象操作即将发生或已经发生的方法名中要使用did或will
-(NSUndoManager *) windowWillReturnUndoManager:(NSWindow *)window;
用于询问委托对象可否执行某操作的方法名中可使用did或will,但最好使用should
-(BOOL)windowShouldClose:(id)sender;
4.方法参数
命名方法参数时要考虑如下规则:
如同方法名,参数名小写第一个单词的首字符,大写后继单词的首字符。应选择与方法名连在一起读起来通顺的参数名。
如:removeObject:(id)anObject
不要在参数名中使用pointer或ptr,让参数的类型来说明它是指针
避免使用one, two,...,作为参数名
避免为节省几个字符而缩写
实例变量与常量
声明属性和实例变量
如果属性是用一个名词或动词描述的,格式是:
@property(…) type nounOrVerb;
例如:@property (strong) NSString *title;
@property (assign) BOOLshowsAlpha;
如果声明的属性是用一个形容词描述的,并且属性名称省略了”is”前缀,则指定其getter方法。
例如:@property (assign, getter=isEditable) BOOL editable;
在为类添加实例变量应注意:
避免创建public实例变量
使用@private、@protected显示限定实例变量的访问权限。如果你希望你的类将被继承,而这些子类将需要直接访问数据,使用@protected指令。
常量
枚举常量
使用枚举来定义一组相关的整数常量,枚举常量也要有相应的前缀。大写前缀后紧跟的第一个单词首字母。
其他常量
使用const来修饰浮点常量或彼此没有关联的整数常量。
const常量命名范例:
const float NSLightGray;
避免在程序中直接出现常量,使用超过一次的应以宏定义的形式来替代。宏定义的命名应当能够表达出它的用途,并且用大写字母表示。
二.书写规范
1.方法声明与定义
方法中如果一行有非常多的参数,更好的方式是将每个参数单独拆成一行。如果使用多行,将每个参数前的冒号对齐。
- (void)doSomethingWith:(GTMFoo *)theFoo
rect:(NSRect)theRect
interval:(float)theInterval { ...
}
当第一个关键字比其它的短时,保证下一行至少有4个空格的缩进。这样可以使关键字垂直对齐,而不是使用冒号对齐:
-(void)short:(GTMFoo *)theFoo
longKeyword:(NSRect)theRect
evenLongerKeyword:(float)theInterval{ ...
}
-或者+与返回类型之间,需要有空格。参数列表中,只有参数之间有空格。
2.方法调用
方法调用时,所有参数应该在同一行。
[myObjectdoFooWith:arg1 name:arg2 error:arg3];
或者每行一个参数,以冒号对齐:
[myObjectdoFooWith:arg1
name:arg2
error:arg3];
与方法定义和方法声明一样,当关键字的长度不足以以冒号对齐时,下一行都要以四个空格进行缩进。
[myObjshort:arg1
longKeyword:arg2
evenLongerKeyword:arg3];
3.变量的声明
变量名必须起有意义的名字,使其它人可以很容易读懂变量所代表的意义。与方法命名一样,首字母小写。
对于一些特殊类型的变量,命名时要带上类型,如NSArray的变量命名为xxxArray,其他的如xxxDictionary,xxxSize等。这样就可以从名称上知道是什么类型的变量。千万不能将NSArray的变量命名为xxxDictionary。
成员变量使用“_”作为前缀。
三.编码的排版格式
1空格的使用
代码的缩进应使用空格(SPACE),不能使用制表符(TAB),并且缩进以2个字符为单位。
关键字与其后的表达式之间要有空格,如:if (expr)或for (expr)
单目操作符不应与它们的操作数分开(如’!’和’^’等)。
除‘,’外,其它双目操作符应与它们的操作数用空格隔开。如:
i=i+1;//错误的写法,操作符两端没有空格
i = i + 1;//正确的写法
if(a>b)//错误的写法,逻辑判断符号两端没有空格
if(a > b)//正确的写法
.h中协议<>前面有一个空格。
.h中成员声明时,类型与变量之间至少有1个空格。*号靠近变量,不靠近类型。
@property后留1个空格,()里面,逗号紧跟前一变量,与后一变量之间留1个空格。()外面,先留1个空格,再声明属性。
方法的+,-后面与()之间留1个空格。
返回类型与*之间留1个空格,方法参数中返回类型与*之间留1个空格。
在多参数方法中,每个参数后面都有1个空格。
2关于空行
1) .h中的空行
文件说明与#import之间空1行
#import之间,如果需要分类区别,各类别之间空1行。
#import与@class之间空2行。
@interface与@class之间空1行。
头文件{}里面,空1行开始声明对象成员,如果需要分类区别,各类别之间空1行。
头文件{}外,空1行书写属性,如果需要分类区别,各类别之间空1行。
属性下面空1行开始写方法,如果需要分类区别,各类别之间空1行。
方法声明完后,与@end空1行。
如果需要声明protocol,空2行接着写。通常protocol写在@end后面,但是声明在@interface之前。
2) .m中的空行
文件说明与#import之间空1行
#import之间,如果需要分类区别,各类别之间空1行。
@implementation和@synthesize之间空1行,如果需要分类区别,各类别之间空1行。
@synthesize与方法之间空1行。
方法与方法之间空1行。
3)方法里面的空行
变量声明后需要空1行,如果需要分类区别,各类别之间空1行。
条件、循环和选择语句,整个语句结束,需要空1行。
各功能块之间空1行。
最后一个括弧之前不空行。
注释与代码之间不空行。
#pragma mark与方法之间空1行。
4)每行代码最好不超过100个字符。
四.注意事项
1.BOOL
Ojbective-C中定义BOOL为无符号字符型,这意味着BOOL类型可以有不同于1或者0的值。不要直接把整形转换成BOOL。常见的错误包括将数组的大小、指针值及位运算的结果直接转换成BOOL,这取决于整型结果的最后一个字节,可能产生一个NO的值。当转换整形至BOOL时,使用三目操作符来返回YES或者NO。
对BOOL使用逻辑运算符(&&,||和!)是合法的,返回值也可以安全地转换成BOOL,不需要使用三目操作符。
错误的用法:
-(BOOL)isBold {
return[self fontTraits] & NSFontBoldTrait;}
-(BOOL)isValid {
return[self stringValue]; }
正确的用法:
-(BOOL)isBold {
return([self fontTraits] & NSFontBoldTrait) ? YES : NO;
}
-(BOOL)isEnabled {
return[self isValid] && [self isBold];
}
同样的,不要直接比较BOOL变量与YES/NO。不仅影响可读性,结果可能与你想的不同。
错误的用法:
BOOLgreat = [foo isGreat];
if(great == YES)
正确的用法:
BOOLgreat = [foo isGreat];
if(great)
2.点引用
点引用是Objective-C2.0的风格,它被使用于简单的属性set、get操作,但对象的其他行为不应该使用它。
正确的做法:
NSString*oldName = myObject.name;
myObject.name= @"Alice";
错误的做法:
NSArray*array = [NSArray arrayWithObject:@"hello"];
NSUIntegernumberOfItems = array.count;// not aproperty
array.release;// nota property
����t�#