IOS编码规范整理后1018Word格式文档下载.docx
《IOS编码规范整理后1018Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《IOS编码规范整理后1018Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
UIGraphicsGetCurrentContext()//函数
NSCellDisabled//常量
(d)
避免给方法名加下划线前缀来表示为私有方法(给实例变量加下划线前缀来表示私有变量是允许的)。
苹果保留了此约定的使用。
类名、协议名
类名应当包含能清晰指出该类的功能的名词。
▪
类名,类别名和协议名的首字母大写,使用首字母大写的形式分割单词
在面向特定应用的代码中,类名应尽量避免使用前缀,每个类都使用相同的前缀影响可读性。
协议头文件里的协议名不要和类名混淆。
LoginDelegate//协议名,加上Delegate
Login//不好。
看上去像一个类名。
(e)方法名
方法的参数采用“驼峰”命名法
表示操作对象的方法,用动词开始命名。
-(void)invokeWithTarget:
(id)target;
多个参数时,每个参数使用参数标签
-(void)sendAction:
(SEL)aSelector
to:
(id)anObject
forAllCells:
(BOOL)flag正确
(SEL)aSelector:
(id)anObject:
(BOOL)flag错误
方法名称要清晰的表达出方法的功能。
-(id)viewWithTag:
(NSInteger)aTag;
正确
-(id)taggedView:
(int)aTag;
错误
当创建一个比继承的方法参数更多的方法时,在继承的方法后边添
加新的关键字。
-(id)initWithFrame:
(CGRect)frameRect;
//UIView,NSView
(CGRect)frameRect
mode:
(int)aMode
numberOfRows:
(int)rowsHigh//NSMatrix,asubclass
numberOfColumns:
(int)colsWide;
//ofNSView
不要使用“and”来连接那些作为receiver属性的关键字。
-(int)runModalForDirectory:
(NSString*)path
file:
(NSString*)name
types:
(NSArray*)fileTypes;
正确;
andFile:
andTypes:
错误
方法描述了两个分离的动作,用“and”连接它们;
-(BOOL)opneFile:
(NSString*)fulPath
withApplication:
(NSString*)appName
andDeactiovation:
(BOOL)flag;
方法名应简短清晰,但不能因简短牺牲清晰
insertObject:
atIndex:
//好
insert:
at:
//不好,不够清晰;
removeObjectAtIndex:
//好
removeObject:
//好,因为它移除参数提及的对象;
remove:
//不清晰,要移除什么?
方法名应尽量全拼,即使单词很长。
因为你写的缩写不一定是广为
人知的,因为开发者有着各自的文化和语言背景。
destinationSelection:
destSel:
//不好
setBackgroundColor;
setBkgdColor:
//不好
当然,少量的缩写是通常所见和使用了很长历史的可以排除在外。
alloc,alt,app,calc,dealloc,func,horiz,info,init,int,max,min,
msg,nib,pboard,rect,Rep,temp,vert等。
还有计算机工业常用的,
ASCII,PDF,XML,HTML,URL,RTF,HTTP,TIFF,JPG,PNG,FIG,
LZW,ROM,RGB,CMYK,MIDI,FTP等。
API方法名避免有歧义,即能别理解一种以上的意思。
sendPort:
//不好,是发送端口号还是要返回一个端口号?
如果不需要重写getter方法时,getter的方法名和变量名应相同。
不允许使用“get”前缀。
-(id)getDelegate;
//禁止
-(id)delegate;
//对头
重写getter时可以使用,例如:
@property(getter=getFontSize)NSIntegerfontSize;
访问器方法根据属性名称:
如果属性为名词,格式为
-(type)noun;
-(void)setNoun:
(type)aNoun;
如果属性为形容词,格式为
-(BOOL)isAdjective;
-(void)setAdjective:
(BOOL)flag;
如果属性为动词,格式为
-(BOOL)verbObject;
-(void)setVerbObject:
不要把动词用分词的形式转成形容词,例如:
-(void)setAcceptsGlyphInfo:
-(void)setGlyphInfoAccepted:
可以使用情态动词(can,should,will等)明确意思,但不能用do,
does。
只有方法间接返回对象和值的时候使用“get”。
只有在多个条目需要
被返回的时候才能使用如下命名:
-(void)getLineDash:
(float*)pattern
count:
(int*)countphase:
(float*)phase;
不同类里做相同功能的方法应该有相同的方法名称,即一致性。
前缀有规定的格式:
包含两到三个大写字母,不能使用下划线或者“subprefixes”.标准如:
NS,AB,IB等。
在面向多应用的代码中,推荐使用前缀。
GTMSendMessage命名classes,protocols,functions,constants,typedefstructures时使用前缀。
命名methods时不要使用前缀;
方法是存在于定义它们的类所创建的namespace里。
也不要在命名结构体字段时使用前缀。
▪如果你是一个大cocoa框架的子类,想绝对确定你的私有方法有一个不同于其他子类的名字,你可以添加一个自己的前缀给私有方法。
这个前缀尽可能独一的,基于你的公司或工程的缩写格式“XX_method”.
本规则仅针对Objective-C代码,C++代码使用C++的编码习惯。
2.变量名
变量名应使用容易意会的应用全称,命名使用“驼峰”表示法。
二格式化代码
1.指针”*”号的位置,“*”前加空格,紧跟参数名
如:
UITextField*mTextField;
2.每行的长度
每行的长度尽量在100个字符之内,保持美观大方。
3.方法的声明和定义
(a)在“-”或者“+”和返回值之间留1个空格,方法名和第一个参数间不留。
-(void)doSomethingWithString:
(NSString*)theString{
//dosomething
}
(b)当参数过长时,每个参数占用一行,以冒号对齐。
-(void)doSomethingWith:
(GTMFoo*)theFoo
rect:
(NSRect)theRect
interval:
(float)theInterval{
//dosomething
(c)
如果方法名比参数名短,每个参数占用一行,至少缩进4个字符,且为垂直对齐(而非使用冒号对齐)。
-(void)short:
longKeyword:
evenLongerKeyword:
//dosomething
5.方法的调用
(a)调用方法沿用声明方法的习惯。
例外:
如果给定源文件已经遵从某种习惯,继
续遵从那种习惯。
(b)
所有参数应在同一行中,或者每个参数占用一行且使用冒号对齐。
[myObjectdoFooWith:
arg1name:
arg2error:
arg3];
或
arg1
name:
arg2
error:
(c)
和方法的声明一样,如果无法使用冒号对齐时,每个参数一行、缩进4个字符、
垂直对其(而非使用冒号对齐)。
[myObjshort:
arg1
evenLongerKeyword:
(d)@public和@private
▪@public和@private使用单独一行,且缩进1个字符
(e)Protocals
类型标示符、代理名称、尖括号间不留空格。
该规则同样适用于:
类声明、实例变量和方法声明。
@interfaceMyProtocoledClass:
NSObject<
NSWindowDelegate>
{
@private
id<
MyFancyDelegate>
delegate;
-(void)setDelegate:
(id<
)delegate;
@end
三Cocoa和Objective-C特有的规则
1.成员变量
◦成员变量使用@private。
@interfaceMyClass:
NSObject{
idmyInstanceVariable;
//publicaccessors,settertakesownership
-(id)myInstanceVariable;
-(void)setMyInstanceVariable:
(id)theVar;
2.IndentifyDesignatedInitializer
一个精心设计的初始化方法应当完成以下步骤来确保适当的检测和误差传播。
▪通过调用super的指定初始器重新分配self;
▪检测返回值和nil对比,这可以指出一些发生在父类的初始器里的错误。
▪如果初始化当前类时发生了一个错误,释放掉该类对象并返回nil。
如下所示:
-(id)init{
self=[superinit];
//Calladesignatedinitializerhere;
if(self!
=nil){
//Initializeobject...
if(someError){
[selfrelease];
self=nil;
}
}
returnself;
}
2.初始化
▪在初始化方法中,不要将变量初始化为“0”或“nil”,那是多余的
▪内存中所有的新创建的对象(isa除外)都是0,所以不需要重复初始化为“0”或“nil”,避免显式的调用+new方法
▪禁止直接调用NSObject的类方法+new,也不要在子类中重载它。
使用alloc和init方法
4.#importVS#include
▪使用#import引入Ojbective-C和Ojbective-C++头文件,使用,#include引入C和C++头文件
▪import根框架(rootframeworks),而非各单个文件
▪虽然有时我们仅需要框架(如Cocoa或Foundation)的某几个头文件,但引入根文件编译器会运行的更快。
因为根框架(rootframeworks),一般会预编译,所以加载会更快。
再次强调:
使用#import而非#include来引入Objective-C框架。
#import<
Foundation/NSArray.h>
#import<
Foundation/NSString.h>
...
Foundation/Foundation.h>
//正确
5.创建对象时autorelease与release的使用
▪一般情况下不用的对象需要release,不建议使用autorelease,在release的时候要严格按照内存管理的方法进行。
在以下两种情况下需要使用autorelease:
(a)方法返回指针类型的对象时需要用到autorelease
-(NSMutableArray*)getBookmarkPreset{
//returnobjectshouldautorelease
NSMutableArray*bookMarkList=[[[NSMutableArrayalloc]init]autorelease];
//dosomething
returnbookMarkList;
(b)方法的逻辑判断比较复杂,有可能提前返回的情况下,建议使用autorelease,虽然这样会稍微有点慢,但这样可以阻止因为提前return或其他意外情况导致的内存泄露。
MyController*controller=[[[MyControlleralloc]init]autorelease];
//...这里的代码可能会提前return...
[controllerrelease];
6.先release,再retain
在为对象赋值时,遵从“先release,再retain”
在将一个新创建的对象赋给变量时,要先将旧对象release掉,否则会内存泄露。
-(void)setFoo:
(GMFoo*)aFoo{
[foo_release];
foo_=[aFooretain];
}
▪dealloc的顺序要与变量声明的顺序相同,这有利于review代码
▪NSString的属性的setter使用“copy”,禁止使用retain,以防止意外的修改了NSString变量的值。
-(void)setFoo:
(NSString*)aFoo{
[foo_autorelease];
foo_=[aFoocopy];
或
@property(nonatomic,copy)NSString*aString;
7.对nil的检查
▪仅在有业务逻辑需求时检查nil,而非为了防止崩溃
8.BOOL陷阱
将int值转换为BOOL时应特别小心。
避免直接和YES比较
Objective-C中,BOOL被定义为unsignedchar,这意味着除了YES
(1)和NO(0)外它还可以是其他值。
禁止将int直接转换为BOOL。
常见的错误包括:
将数组的大小、指针值或位运算符的结果转换为
BOOL,因为该BOOL值的结果取决于整型值的最后一位
将整型值转换为BOOL的方法:
使用三元运算符返回YES/NO,或使用位运算符(&
&
||,!
)
BOOL、_Bool和bool之间的转换是安全的,但是BOOL和Boolean间的转换不是安全的,所以将Boolean看成整型值。
在Objective-C中,只允许使用BOOL,如:
//禁止
-(BOOL)isBold{
return[selffontTraits]&
NSFontBoldTrait;
//&
得出来的值是int不是Bool,避免出现返回int。
-(BOOL)isValid{
return[selfstringValue];
}
//对头
-(BOOL)isBold{
return([selffontTraits]&
NSFontBoldTrait)?
YES:
NO;
-(BOOL)isValid{
return[selfstringValue]!
=nil;
}
-(BOOL)isEnabled{
return[selfisValid]&
[selfisBold];
禁止直接将BOOL和YES/NO比较,如:
//禁止
BOOLgreat=[fooisGreat];
if(great==YES)
...
//对头
BOOLgreat=[fooisGreat];
if(great)
9.属性
通过使用声明property和synthesize组合来避免显式声明公共实例变量。
如果要显式声明一个实例变量,要么@private或者@protected。
如果该类派生子类,子类需要访问该类数据,使用@protected。
▪位置:
属性的声明紧随成员变量块之后,中间空一行,无缩进。
▪严把权限:
对不需要外部修改的属性使用readonly
▪NSString使用copy而非retain。
▪一般使用nonatomic,除非特殊情况下使用atomic,例如多线程。
四CocoaPattern(模式)
1.DelegatePattern(委托模式)
delegate对象使用assign,禁止使用retain。
因为retain会导致循环索引导致内存泄露,
并且此类型的内存泄露无法被Instrument发现,极难调试
2.Model/View/Controller
▪Model和View分离。
▪不要在与view相关的类中添加过多的业务逻辑代码,这让代码的可重用性很差。
▪Controller负责业务逻辑代码,且Controller的代码与view尽量无关
▪使用@protocal定义回调APIs,如果并非所有方法都是必须的,可选使用@optional标示,必选使用@required标识.
五其他
1.init方法和dealloc
init和dealloc方法是是最常用的方法,所以将他们放在类实现的开始位置
(a)使用空格将相同的变量、属性对齐,使用换行分组
(b)在设定视图frame时,会随屏幕大小变化的视图使用controller.view.frame的相对数值。
//MyViewController.m
-(void)viewDidLoad{
[superviewDidLoad];
//Dosomething...
UIScrollView*mScrollView=[[UIScrollViewalloc]initWithFrame:
CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height)];
[self.viewaddSubview:
mScrollView];
2.多view视图排版
有多个view同时在一个view上时,其之间的间距用变量来设定;
//MyViewController.m
[superviewDidLoad];
inti=0;
UILabel*l1=[[UILabelalloc]initWithFrame:
CGRectMake(0,i,100,30)];
[self.viewaddSubview:
l1];
[l1release];
i+=50;
UILabel*l2=[[UILabelalloc]initWithFrame:
l2];
[l2release];
i+=60;
UILabel*l3=[[UILabelalloc]initWithFrame:
l3];
[l3release];
3.开发中尽可能使用代码,xib尽少使用。