目录
前言
虽然编码规范是一件很个性化的事情,但是一个良好的代码规范是一种共识。下面的内容结合了参考文章以及个人的编码习惯而形成的规范。
行宽
尽量保持在100以内,具体设置如下
Xcode->Preferences->Text Editing->Page guide at column
类型
- 使用到整形变量时,建议使用NSInteger NSUInteger,不建议使用int,uint 。
- 使用float时,建议使用CGFloat
常量
建议
static NSString *const PLMessageCountChanageNotificationName = @"MessageCountChanageNotification"
static NSUInteger const PLRetryMaxCount = 5
不建议
#define PLMessageCountChanageNotificationName @"MessageCountChanageNotification"
#define PLRetryMaxCount 5
变量
- 遵循驼峰模式即可
- 对于实例变量建议以下划线开始命名
@interface Foo()
{
NSString *_name
}
@end
字面值
对于NSString, NSDictionary, NSArray,以及 NSNumber 支持语法糖
建议
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone": @"Kate", @"iPad": @"Kamal", @"Mobile Web": @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingStreetNumber = @10018;
不建议
NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingStreetNumber = [NSNumber numberWithInteger:10018];
枚举
建议
typedef NS_ENUM(NSInteger, UIViewAnimationCurve) {
UIViewAnimationCurveEaseInOut, // slow at beginning and end
UIViewAnimationCurveEaseIn, // slow at beginning
UIViewAnimationCurveEaseOut, // slow at end
UIViewAnimationCurveLinear,
};
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
不建议
enum UIViewAnimationCurve {
UIViewAnimationCurveEaseInOut, // slow at beginning and end
UIViewAnimationCurveEaseIn, // slow at beginning
UIViewAnimationCurveEaseOut, // slow at end
UIViewAnimationCurveLinear,
};
控制语句
关于if
建议
if(condition) {
//...
} else {
//...
}
不建议
if(condition)
{
//..
}
else
{
//..
}
关于switch
括号不是必须的,为了代码结构层次清晰,建议加上括号。
switch(condition){
case 1:
{
//one line or multi-line
}
break;
default:
break;
}
对于枚举类型的switch,可以不需要default
UIViewAnimationCurve curveType = UIViewAnimationCurveEaseInOut;
switch(curveType) {
case UIViewAnimationCurveEaseInOut:
{
}
break;
case UIViewAnimationCurveEaseIn:
{
}
break;
case UIViewAnimationCurveEaseOut:
{
}
break;
case UIViewAnimationCurveLinear:
{
}
break;
}
关于for循环
对于集合类型(array,set) 建议使用 enumerateObjectsUsingBlock
NSArray *nameArray = @[@"Kita","jonas"];
[nameArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//...
}];
其次可以选择for in 如果不需要索引的话
for(NSString *name in nameArray) {
//...
}
属性
- 对于属性修饰符要全都指示出来,对于纯量类型默认是(atomic,assign),对于对象类型默认是(atomic,strong)。权限修饰符默认readwrite可以不写,一般情况下属性都是readwrite,对于只读属性需要写明readonly
- 对于有可变类型的类(NSString,NSArray,NSDictionary,NSSet) 建议使用copy,是因为有可能引用可变对象
建议
@property(nonatomic,copy) NSString *name;
@property(nonatomic,strong) UIView *containerView;
不建议
@property(nonatomic,strong) NSString *name;
@property(nonatomic) UIView *containerView;
方法
方法类型(-/+)后需要空一格
建议
- (void)setTitle:(nullable NSString *)title forState:(UIControlState)state;
不建议
-(void)setTitle:(nullable NSString *)title forState:(UIControlState)state;
注释
文件注释
注释是代码可读性的关键,最好的代码应该自成文档。
使用Xcode Snippets创建模板
模板建议
/**
**<#文件内容的简要描述#>
**<#代码作者#>
**<#版权信息声明(如:Copyright 2008 Google Inc.)#>
**<#必要的话,加上许可证样板。为项目选择一个合适的授权样板(例如,Apache 2.0, BSD, LGPL, GPL)。#>
*/
其他注释(类注释,方法注释等)
xcode8 建议使用自带注释快捷键 command+option+/
xcode8以下版本建议使用vvdocumenter注释插件
代码结构组织
#pragma mark - Lifecycle
- (instancetype)init {}
- (void)viewDidLoad {}
- (void)viewWillAppear:(BOOL)animated {}
- (void)didReceiveMemoryWarning {}
- (void)dealloc {}
#pragma mark - Getter
- (NSString *)name;
#pragma mark - Setter
- (void)setName:(NSString *)name;
#pragma mark - Public Methods
- (void)publicMethod {}
#pragma mark - Private Methods
- (void)privateMethod {}
#pragma mark - Some Delegate
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone {}
#pragma mark - IBActions
- (IBAction)submitData:(id)sender {}
使用NSCAsserts作为断言
使用NSCAssert而不是assert 或者NSAssert
是因为NSAssert宏内部持有self,尤其在block中,极易引起retain cycle。
使用CGRect函数
建议
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
CGRect frame = CGRectMake(0.0, 0.0, width, height);
不建议
CGRect frame = self.view.frame;
CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;
CGRect frame = (CGRect){ .origin = CGPointZero, .size = frame.size };