1. 目的
1.1增加代码可读性和可维护性,养成良好的代码习惯;
1.2为了更加有效地开发和维护内部项目,积累代码库。
2. 原则
只遵循苹果公司发布代码中主流的代码风格。
3. 命名规范
-
3.1 变量、类名、函数名使用波浪式命名法,即碰到一个新的单词则使用大写字母开头,尽量使用完整的单词命名,不采用缩写的单词命名;
3.2 类名使用大写字母打头,最好加上项目名称缩写作为前缀,如:GetNumber
3.3 类的成员变量,使用下划线开头,如:_age; - 3.4 无论是对象方法还是类方法,方法名一律以小写字母开头,如:createTableView;
3.5 临时变量和函数参数以小写字母开头;
3.6 const常量使用小写字母k开头。
4. 书写规范
4.1 临时变量的声明,必须赋值初始化,如:
NSInteger x = 0;
4.2 临时变量的声明,必须另起一行:
NSInteger x = 0;
NSInteger y = 0;
4.3 临时变量的声明语句写完后,必须隔行开始书写逻辑代码,逻辑代码中 可以穿插临时变量的声明语句,同样必须隔行书写,如:
NSString *midLocalURL = [[g_pLCLog docDir]
stringByAppendingPathComponent:[NSString stringWithFormat:@"%@,%d", fileID, [g_pModel midPhotoSize]]];
if ([g_pFileMgr fileExistsAtPath:midLocalURL])
{
[g_pFileMgr removeItemAtPath:midLocalURL error:nil]);
}
UIImage *midImage = [image resizedImage:CGSizeMake([g_pModel midPhotoSize], [g_pModel midPhotoSize]) interpolationQuality:kCGInterpolationDefault];
NSData *midData = UIImageJPEGRepresentation(midImage, kImageCompressionQuality);
CHECKB([midData writeToFile:midLocalURL atomically:YES]);
4.4 遇到新的代码块,必须隔行书写,包括函数的实现、if、switch 分支语句、 while、do...while、for 循环语句等,例如:
NSString *channelID = [g_pModel channelID];
if ([channelID length] == 0)
{
channelID = @"iTunes";
}
[label setText:LCString(@"TEST_VERSION")];
4.5 所有的二元运算符,以空格隔开,如 x += 12; 不应写成 x+=12;4.6 所有的逗号后都要追加一个空格,如:CGRectMake(1, 3, 5, 7);4.7 指针的声明,*写在变量前,类名和*之间用空格隔开,禁止写成 C/C++提倡的写法:NSObject* obj = nil;应写成 NSObject *obj = nil;4.8 尽量使用 NSInteger 取代 int、使用 NSUInteger 取代 unsigned int;
4.6 代码的注释应写在对应代码的上方或右边,禁止将注释写在对应代码的下方;
4.7
- 在方法之间应该有且只有一行,这样有利于在视觉上更清晰和更易于组织。在方法内的空白应该分离功能,但通常都抽离出来成为一个新方法。
- 优先使用auto-synthesis。但如果有必要,@synthesize和@dynamic应该在实现中每个都声明新的一行。
- 应该避免以冒号对齐的方式来调用方法。因为有时方法签名可能有3个以上的冒号和冒号对齐会使代码更加易读。请不要这样做,尽管冒号对齐的方法包含代码块,因为Xcode的对齐方式令它难以辨认。
应该:
// blocks are easily readable
[UIView animateWithDuration:1.0 animations:^{
// something
} completion:^(BOOL finished) {
// something
}];
不应该:
// colon-aligning makes the block indentation hard to read
[UIView animateWithDuration:1.0
animations:^{
// something
}
completion:^(BOOL finished) {
// something
}];
4.11 不推荐在同一个方法中书写过多的代码,可以将一个功能封装成一个方法,这样代码看起来会很整洁。
#pragma mark 点击下一题
//该方法调用了很多子方法
- (IBAction)nextQuestion
{
//1.增加索引
self.index ++;
self.nextBtn.enabled = (self.index != self.questions.count - 1);
//2.取出模型
HQQuestion *question = self.questions[self.index];
//3.设置控件的数据
[self setData:question];
//4.添加正确答案
[self addAnswer:question];
//5.添加待选项
[self addOption:question];
}
//分别编写各个子方法
#pragma mark 设置控件数据
- (void)setData:(HQQuestion *)question
{
//code
}
#pragma mark 添加正确答案
- (void)addAnswer:(HQQuestion *)question
{
//code
}
#pragma mark 添加待选项
- (void)addOption:(HQQuestion *)question
{
//code
}
5. 注释
5.1 成员变量推荐使用文档注释法
/**序号*/
@property (weak, nonatomic) IBOutlet UILabel *noLabel;
/**标题*/
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
/**头像(图标)*/
@property (weak, nonatomic) IBOutlet UIButton *iconBtn;
/**下一题按钮*/
@property (weak, nonatomic) IBOutlet UIButton *nextBtn;
/**遮盖*/
@property (weak,nonatomic) IBOutlet UIButton *cover;
/**所有的题目*/
@property (<span style="font-family: Arial, Helvetica, sans-serif;">strong,</span><span style="font-family: Arial, Helvetica, sans-serif;">nonatomic) NSArray *questions;</span>
/**当前是第几题(当前题目的索引)*/
@property (<span style="font-family: Arial, Helvetica, sans-serif;">assign,</span><span style="font-family: Arial, Helvetica, sans-serif;">nonatomic) int index;</span>
6.其他规范
6.1 语言
应该使用US英语。
应该:
UIColor *myColor = [UIColor whiteColor];
不应该:
UIColor *myColour = [UIColor whiteColor];
6.2 代码组织
在函数分组和protocol/delegate实现中使用#pragma mark -来分类方法,要遵循以下一般结构:
#pragma mark - Lifecycle
- (instancetype)init {}
- (void)dealloc {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
#pragma mark - Custom Accessors
- (void)setCustomProperty:(id)value {}
- (id)customProperty {}
#pragma mark - IBActions
- (IBAction)submitData:(id)sender {}
#pragma mark - Public
- (void)publicMethod {}
#pragma mark - Private
- (void)privateMethod {}
#pragma mark - Protocol conformance
#pragma mark - UITextFieldDelegate
#pragma mark - UITableViewDataSource
#pragma mark - UITableViewDelegate
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone {}
#pragma mark - NSObject
- (NSString *)description {}
6.3 属性特性
所有属性特性应该显式地列出来,有助于新手阅读代码。属性特性的顺序应该是storage、atomicity,与在Interface Builder连接UI元素时自动生成代码一致。
storage 规范如下:
copy:NSString
strong:一般对象
weak:UI控件
assign:基本数据类型
注意: NSString应该使用copy而不是strong的属性特性。为什么?即使你声明一个NSString的属性,有人可能传入一个NSMutableString的实例,然后在你没有注意的情况下修改它。
应该:
@property (copy, nonatomic) NSString *tutorialName;
@property (<span style="font-family: Arial, Helvetica, sans-serif;">weak, </span>nonatomic) IBOutlet UIView *containerView;
6.4 条件语句
条件语句主体为了防止出错应该使用大括号包围,即使条件语句主体能够不用大括号编写(如,只用一行代码)。
6.5 Init方法
if (!error) {
return success;
}
6.5 Init方法
Init方法应该遵循Apple生成代码模板的命名规则,返回类型应该使用instancetype而不是id。
- (instancetype)init {
if (self = [super init]) {
// ...
}
return self;
}
6.6 类构造方法
当类构造方法被使用时,它应该返回类型是instancetype而不是id。这样确保编译器正确地推断结果类型。
@interface Airplane
+ (instancetype)airplaneWithType:(RWTAirplaneType)type;
@end
6.7 黄金路径
当使用条件语句编码时,左手边的代码应该是"golden" 或 "happy"路径。也就是不要嵌套if语句,多个返回语句也是OK。
应该:
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
//Do something important
}
不应该:
- (void)someMethod {
if ([someOther boolValue]) {
//Do something important
}
}
6.8 单例模式
单例对象应该使用线程安全模式来创建共享实例。
+ (instancetype)sharedInstance {
static id sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}