Objective-C开发编码规范:4大方面解决开发中的规范性问题时间:15-05-0716:15:13点击:73257325来源:QianKaiLuObjective-C编码规范,内容来自苹果、谷歌的文档翻译,自己的编码经验和对其它资料的总结。概要Objective-C是一门面向对象的动态编程语言,主要用于编写iOS和Mac应用程序。关于Objective-C的编码规范,苹果和谷歌都已经有很好的总结:AppleCodingGuidelinesforCocoaGoogleObjective-CStyleGuide本文主要整合了对上述文档的翻译、作者自己的编程经验和其他的相关资料,为公司总结出一份通用的编码规范。代码格式使用空格而不是制表符Tab不要在工程里使用Tab键,使用空格来进行缩进。在XcodePreferencesTextEditing将Tab和自动缩进都设置为4个空格。(Google的标准是使用两个空格来缩进,但这里还是推荐使用Xcode默认的设置。)每一行的最大长度同样的,在XcodePreferencesTextEditingPageguideatcolumn:中将最大行长设置为80,过长的一行代码将会导致可读性问题。函数的书写一个典型的Objective-C函数应该是这样的:-(void)writeVideoFrameWithData:(NSData*)frameDatatimeStamp:(int)timeStamp{...}在-和(void)之间应该有一个空格,第一个大括号{的位置在函数所在行的末尾,同样应该有一个空格。(我司的C语言规范要求是第一个大括号单独占一行,但考虑到OC较长的函数名和苹果SDK代码的风格,还是将大括号放在行末。)如果一个函数有特别多的参数或者名称很长,应该将其按照:来对齐分行显示:-(id)initWithModel:(IPCModle)modelConnectType:(IPCConnectType)connectTypeResolution:(IPCResolution)resolutionAuthName:(NSString*)authNamePassword:(NSString*)passwordMAC:(NSString*)macAzIp:(NSString*)az_ipAzDns:(NSString*)az_dnsToken:(NSString*)tokenEmail:(NSString*)emailDelegate:(id)delegate;在分行时,如果第一段名称过短,后续名称可以以Tab的长度(4个空格)为单位进行缩进:-(void)short:(GTMFoo*)theFoolongKeyword:(NSRect)theRectevenLongerKeyword:(float)theIntervalerror:(NSError**)theError{...}函数调用函数调用的格式和书写差不多,可以按照函数的长短来选择写在一行或者分成多行://写在⼀一⾏行[myObjectdoFooWith:arg1name:arg2error:arg3];//分⾏行写,按照':'对⻬齐[myObjectdoFooWith:arg1name:arg2error:arg3];//第⼀一段名称过短的话后续可以进⾏行缩进[myObjshort:arg1longKeyword:arg2evenLongerKeyword:arg3error:arg4];以下写法是错误的://错误,要么写在⼀一⾏行,要么全部分⾏行[myObjectdoFooWith:arg1name:arg2error:arg3];[myObjectdoFooWith:arg1name:arg2error:arg3];//错误,按照':'来对⻬齐,⽽而不是关键字[myObjectdoFooWith:arg1name:arg2error:arg3];@public和@private标记符@public和@private标记符应该以一个空格来进行缩进:@interfaceMyClass:NSObject{@public...@private...}@end协议(Protocols)在书写协议的时候注意用括起来的协议和类型名之间是没有空格的,比如IPCConnectHandler(),这个规则适用所有书写协议的地方,包括函数声明、类声明、实例变量等等:@interfaceMyProtocoledClass:NSObject{@privateid_delegate;}-(void)setDelegate:(id)aDelegate;@end闭包(Blocks)根据block的长度,有不同的书写规则:较短的block可以写在一行内。如果分行显示的话,block的右括号}应该和调用block那行代码的第一个非空字符对齐。block内的代码采用4个空格的缩进。如果block过于庞大,应该单独声明成一个变量来使用。^和(之间,^和{之间都没有空格,参数列表的右括号)和{之间有一个空格。//较短的block写在⼀一⾏行内[operationsetCompletionBlock:^{[selfonOperationDone];}];//分⾏行书写的block,内部使⽤用4空格缩进[operationsetCompletionBlock:^{[self.delegatenewDataAvailable];}];//使⽤用C语⾔言API调⽤用的block遵循同样的书写规则dispatch_async(_fileIOQueue,^{NSString*path=[selfsessionFilePath];if(path){//...}});//较⻓长的block关键字可以缩进后在新⾏行书写,注意block的右括号'}'和调⽤用block那⾏行代码的第⼀一个⾮非空字符对⻬齐[[SessionServicesharedService]loadWindowWithCompletionBlock:^(SessionWindow*window){if(window){[selfwindowDidLoad:window];}else{[selferrorLoadingWindow];}}];//较⻓长的block参数列表同样可以缩进后在新⾏行书写[[SessionServicesharedService]loadWindowWithCompletionBlock:^(SessionWindow*window){if(window){[selfwindowDidLoad:window];}else{[selferrorLoadingWindow];}}];//庞⼤大的block应该单独定义成变量使⽤用void(^largeBlock)(void)=^{//...};[_operationQueueaddOperationWithBlock:largeBlock];//在⼀一个调⽤用中使⽤用多个block,注意到他们不是像函数那样通过':'对⻬齐的,⽽而是同时进⾏行了4个空格的缩进[myObjectdoSomethingWith:arg1firstBlock:^(Foo*a){//...}secondBlock:^(Bar*b){//...}];数据结构的语法糖应该使用可读性更好的语法糖来构造NSArray,NSDictionary等数据结构,避免使用冗长的alloc,init方法。如果构造代码写在一行,需要在括号两端留有一个空格,使得被构造的元素于与构造语法区分开来://正确,在语法糖的[]或者{}两端留有空格NSArray*array=@[[foodescription],@AnotherString,[bardescription]];NSDictionary*dict=@{NSForegroundColorAttributeName:[NSColorredColor]};//不正确,不留有空格降低了可读性NSArray*array=@[[foodescription],[bardescription]];NSDictionary*dict=@{NSForegroundColorAttributeName:[NSColorredColor]};如果构造代码不写在一行内,构造元素需要使用两个空格来进行缩进,右括号]或者}写在新的一行,并且与调用语法糖那行代码的第一个非空字符对齐:NSArray*array=@[@This,@is,@an,@array];NSDictionary*dictionary=@{NSFontAttributeName:[NSFontfontWithName:@Helvetica-Boldsize:12],NSForegroundColorAttributeName:fontColor};构造字典时,字典的Key和Value与中间的冒号:都要留有一个空格,多行书写时,也可以将Value对齐://正确,冒号':'前后留有⼀一个空格NSDictionary*option1=@{NSFontAttributeName:[NSFontfontWithName:@Helvetica-Boldsize:12],NSForegroundColorAttributeName:fontColor};//正确,按照Value来对⻬齐NSDictionary*option2=@{NSFontAttributeName:[NSFontfontWithName:@Arialsize:12],NSForegroundColorAttributeName:fontColor};//错误,冒号前应该有⼀一个空格NSDictionary*wrong=@{AKey:@b,BLongerKey:@c,};//错误,每⼀一个元素要么单独成为⼀一⾏行,要么全部写在⼀一⾏行内NSDictionary*alsoWrong=@{AKey:@a,BLongerKey:@b};//错误,在冒号前只能有⼀一个空格,冒号后才可以考虑按照Value对⻬齐NSDictionary*stillWrong=@{AKey:@b,BLongerKey:@c,};命名规范基本原则清晰命名应该尽可能的清晰和简洁,但在Objective-C中,清晰比简洁更重要。由于Xcode强大的自动补全功能,我们不必担心名称过长的问题。//清晰insertObject:atIndex://不清晰,insert的对象类型和at的位置属性没有说明insert:at://清晰removeObjectAtIndex://不清晰,remove的对象类型没有说明,参数的作⽤用没有说明remove:不要使用单词的简写,拼写出完整的单词://清晰destinationSelectionsetBackgroundColor://不清晰,不要使⽤用简写destSelsetBkgdColor:然而,有部分单词简写在Objective-C编码过程中是非常常用的,以至于成为了一种规范,这些简写可以在代码中直接使用,下面列举了部分:alloc==Allocatemax==Maximumalt==Alternatemin==Minimumapp==Applicationmsg==Messagecalc==Calculatenib==InterfaceBuilderarchivedealloc==Deallocatepboard==Pasteboardfunc==Functionrect==Rectanglehoriz==HorizontalRep==Representation(usedinclassnamesuchasNSBitmapImageRep).info==Informationtemp==Temporaryinit==Initializevert==Verticalint==Integer命名方法或者函数时要避免