开发代码规范
风格推荐
仿照 Cocoa 风格来,使用长命名风格,无论是变量,常量,属性,方法,类名等都应该尽量取得有意义。
命名推荐的命名语素顺序是:最开头是命名空间简写,然后越重要、区分度越大的语素越要往前放。经典的结构是:作用范围+限定修饰+类型。
举例:
APIDefaultPageSize //还行,能明白意思了
APIDefaultFetchPageSize //加上些限定更好一些
APIFetchPageSizeDefault //再好些,把重要的往前放
注释
好的方式是尽量让代码可以自表述,而不是依赖注释。
注释应该表达那些代码没有表达以及无法表达的东西。如果一段注释被用于解释一些本应该由这段代码自己表达的东西,我们就应该将这段注释看成一个改变代码结构或编码惯例的信号。我们重命名那些糟糕的方法和类名,而不是用添加注释的方式去修补。我们选择将长函数中的一些代码段抽取出来形成一些小函数,这些小函数的名字可以表述原代码段的意图,而不是对这些代码段进行注释。尽可能的通过代码进行表达。你通过代码所能表达的和你想要表达的所有事情之间的差额将为注释提供了一个合理的候选使用场合。对那些代码无法表达的东西进行注释,而不要仅简单地注释那些代码没有表达的东西。
方法内部禁止使用块注释。除非要临时注释大段代码,一般情况总应使用行注释。
前缀
每个项目都应该有一个三个大写字符的前缀,作为类名的前缀,静态变量等,每个项目都应该有单独的项目前缀,而不是使用公司名字,或者个人名字的缩写来作为项目前缀。
一般来说前缀名取的是项目名拼音的前三个
例如:城俱杯--CJB 数据港--SJG
对于项目名太长的可以用意义的英文的首字母
例如:天津维修资金管理(Tianjin Fix Capital Manage)--TJF FCM
宏定义的前缀用k
(小写)
花括号
花括号的开始部分应该保证在一行的结尾部分,结束部分应该总是有花括号的。
举例:
//Good
if (number == 1) {
[self doThings];
}
//Bad
if (number == 1)
{
[self doThings];
}
//Bad
if (number == 1)
[self doThings];
//Bad
if (number == 1) [self doThings];
//Bad
if (number == 1) { [self doThings]; }
//Good
if (number == 1) {
[self doSomething];
} else {
[self doSomethingElse];
}
//Good
if (number == 1) {
[self doSomething];
} else if (number == 2) {
[self doSomethingElse];
}
//Bad
if (number == 1) {
[self doSomething];
}
else {
[self doSomethingElse];
}
变量
变量名应该是描述性的避免缩写,指针类型的*
号应该和变量名称连在一起,变量名应该以小写字母开头,并写成小驼峰的形式。
举例:
//Good
NSString *carModel = @"Mustang";
CGFloat noteViewWidth = 30;
//Bad
NSString * carModelString = @"Mustang";
CGFloat nwidth = 30;
也可以在变量名后面加上类型名,避免造成混淆。
举例:
NSDate *currentDate = [NSDate date];
NSString *currentDateString = [XYZDateFormatter stringFromDate:currentDate];
OC常用变量类型规范举例:
类型 |
推荐 |
反例 |
---|---|---|
UIImageView |
avatarImageView ,playHolderImageView
|
userPicture ,imageMid ,imageLeft ,cellImage
|
UILabel |
newsTitleLabel ,newsSubTitleLabel
|
cellLable1 ,cellLable2
|
UIButton |
rssButton ,playButton
|
btn1 ,btn2
|
UIView |
CustomView |
line_top ,line_boot
|
UITableView |
ClubMemberTableView |
tableView ,dataTableView
|
方法
方法应该如下面的格式来写:
举例:
//Instance method
- (void)buildJSONRequestFromString:(NSString *)request withTag:(int)tag;
//Class method
+(XYZString *)uppercaseStringFromString:(NSString *)string;
方法名应该是描述性的,应该避免使用以set
或 get
开头来给方法命名,除非是重写set get
方法;
应该避免使用以 is
开头来给方法命名,除非该方法的返回值时bool
类型。
属性
所有的实例变量都应该定义成属性,只有当外部的类需要访问此属性的时候,才把属性定义在头文件里面,避免使用@synthesize
,避免直接访问实例变量,除非在初始化方法中,dealloc
方法中,或者setter
和getter
方法中。
举例:
//Good
self.notes = [[NSArray alloc] init];
//Bad
_notes = [[NSArray alloc] init];
//Good
@interface XYZNoteView : XYZSuperView
@property (nonatomic, strong) NSMutableArray *notes;
@end
//Bad
@interface XYZNoteView : XYZSuperView {
NSArray _notes;
}
@property (nonatomic, strong) NSMutableArray *notes;
@end
属性应该总是用点语法来访问(car.model 而不是 [car model] 或者 [car setModel])
枚举
枚举应该使用NS_ENUM
来定义,而不是C
函数中的样式,像系统类库里面的写法一样:
举例:
typedef NS_ENUM(NSInteger, UIApplicationState) {
UIApplicationStateActive,
UIApplicationStateInactive,
UIApplicationStateBackground
} ;
UIApplicationState(表示该枚举体的使用情境) + Active (区别所在)
布尔值
布尔值应该总是使用BOOL
来进行申明,避免使用C
语言风格的bool
,布尔类型的变量应该用is
开头,
举例:
//Good
if (person.isRunning) {
}
if (!person.isRunning) {
}
//Bad
if (person.isRunning == nil) {
}
if (person.isRunning == NO) {
}
if (person.isRunning == YES) {
}
控制器名、类名
控制器类名遵循标准的类命名规范
(大写的工程前缀 :XYZ+ 大驼峰写法的类描述名:PueInfo + 后缀名:ViewController, TableViewController, CollectionViewController),避免使用缩写(VC, TVC, or CVC)
考虑到加上工程前缀和有意义的类名之后,控制器的类名显得非常长,对控制器的类名作如下的缩写规定:
举例:
1.ViewController简写成Ctrl,XYZPueInfoViewController简写成XYZPueInfoCtrl, CJBLatestNewsListViewController简写成CJBLatestNewsListCtrl;
2.TableViewCell简写成Cell, PersonerImageTableViewCell简写成PersonerImageCell, SetDefultAdressTableViewCell简写成SetDefultAdressCell;
3.JSONModel简写成Model, UserInfoDetailJsonModel简写成UserInfoDetailModel.
类的实现文件
实现文件都是类依赖的方法,组织方法的原则是:用处,我们力图把用处相似的方法写在一块,这样方便管理和修改,方法应该遵循下面的顺序来组织:
1. 构造方法和析构方法
2. 重写父类的方法
3. 自定义的`setter`和`getter`方法
4. 私有的实例方法
5. 共有的实例方法
6. 共有的类方法
每一组之间应该用#pragma mark
分开,后面写上对这一组的描述:
#pragma mark - UIViewController methods
组内部可以进一步细分,但是不要使用连字符,写上对单个方法或函数的描述:
#pragma mark
协议
举例:
@class FODFirstCell;//类的前置申明
@protocol FODFirstViewControllerDelegate <NSObject>
- (void)firstCell:(FODFirstCell *)cell deliverRate:(NSInteger)rate;
@end
@interface FODFirstCell : UITableViewCell
@property (nonatomic ,weak) id<FODFirstViewControllerDelegate> delegate;
@end
if (self.delegate) {
[self.delegate firstCell:self deliverRate:20];
}
协议名的结构:FODFirstCell(类名)+Delegate(代理),保证协议方法的第一个参数是该类本身,后面跟上要传递的参数。
子类,分类,类扩展
- 尽可能少用子类,使用分类或者类扩展来代替子类;
- 如果要扩展现有类的方法,使用分类,类名使用如下样式进行定义:
UIColor+XYZProjectColor UIColor+XYZColorBlend;
- 如果单单想给当前类扩展一个属性的话,尽量使用类扩展,为了保证类的头文件的整洁,要遵循的协议通通写在类扩展里;
举例:
@interface FODFirstViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (strong, nonatomic) NSArray *dataArray;
@end
- 若是必须新建一个子类的话,子类的命名应该个他的父类有所关联。
举例:FODFirstTableViewController : UITableViewController