项目代码规范
1. nil判断
推荐:
if (someObject) { ...
if (![someObject boolValue]) { ...
if (!someObject) { ...
不推荐:
if (someObject == YES) { ... // Wrong
if (myRawValue == YES) { ... // Never do this.
if ([someObject boolValue] == NO) { ...
2. 条件语句尽量少嵌套,适当使用return避免业务的复杂度,提高可读性
推荐:
- (void)someMethod {
if (![someOther boolValue]) {
return;
}
// Do something important
}
if (user.isHappy) {
// Do something
}
else {
// Do something else
}
不推荐:
- (void)someMethod {
if ([someOther boolValue]) {
// Do something important
}
}
if (user.isHappy)
{
// Do something
} else {
// Do something else
}
3. 枚举类型
推荐:
typedef NS_ENUM(NSUInteger, PlayState) {
PlayStateNone,
PlayStateIdle,
PlayStateRunning,
PlayStatePaused
};
不推荐:
typedef NS_ENUM(NSUInteger, State) {
None,
Idle,
Running,
Paused
};
4. 类、方法、属性等命名,做到见名知意,采用驼峰式命名规则.属性命名时,空格靠近属性名(NSString *text),不要写成
NSString* text;
NSString * text;
5. 在方法签名中,在 -/+ 符号后应该有一个空格。方法片段之间也应该有一个空格。不要加and
推荐:
- (void)setExampleText:(NSString *)text image:(UIImage *)image;
不推荐:
- (void)setExampleText:(NSString *)text andImage:(UIImage *)image;
6. 命名尽可能遵守苹果的命名约定,具备描述性
推荐:
UIButton *settingsButton;
不推荐:
UIButton *setBtn;
7. 当访问一个 CGRect
的 x
, y
, width
, height
时,应该使用CGRectGet
推荐:
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);
不推荐:
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;
8. 可变数组和字典
1) addObject之前要非空判断。
2) 取下标的时候要判断是否越界。
3) 取第一个元素或最后一个元素的时候使用firtstObject和lastObject
9. 构建缓存时建议用NSCache 而非NSDictionary
1) NSCache是线程安全的:不编写加锁代码的前提下,多个线程可以同时访问NSCache。
2) NSCache具备自动删减缓冲,本身就是为了管理缓存.
10.通知NSNotification
1) 建议将通知的名字作为常量,保存在一个专门的类中
2) 监听和销毁方法相邻,不要隔太远
11.调试方法前加 #warning 标注,防止忘记还原
12.类布局:初始化和生命周期放最前面,代理懒加载靠后
- (instancetype)init
- (void)dealloc
- (void)viewWillAppear:(BOOL)animated
- (void)viewDidAppear:(BOOL)animated
- (void)viewWillDisappear:(BOOL)animated
- (void)viewDidDisappear:(BOOL)animated
#pragma mark - Override Methods
#pragma mark - Intial Methods
#pragma mark - Network/Data Methods
#pragma mark - Public Methods
#pragma mark - Private Methods
#pragma mark - Delegate
#pragma mark - Lazy Loads
#pragma mark - 系统屏幕方向控制
13. 建议单页代码最好控制在800行以内,每个方法最好不要超过100行
14. 相同的逻辑方法定义避免在多个地方出现,尽量将公用的类、方法抽取出来,尽量封装对外提供接口调用.
15. 头文件.h 属性和方法申明提供必要的注释,保持统一风格
16. 实现类.m 私有属性提供必要注释,方法实现提供 #pragma mark - 方便后期查找
17. 统一末尾后缀,例如UIButton 后缀添加“Button”,NSArray的变量命名为xxxArray等
18. 结果为浮点数,分子应该乘以1.0 防止自动强制转换成整型
19. 当参数过长时,每个参数占用一行,以冒号对齐
20. 图片资源文件以模块区分,尽量一个单独模块,一个图片资源文件夹, 图片命名:采用单词全拼,“模块+功能”命名法,例如 "user_logo@2x"
21. 控制器尽量瘦身,尽量功能区分清晰,根据业务情况采用适合的设计模式. 例如可以单独一个管理类去处理业务,也可以将每个单业务放在控制器的分类扩展中,这样来保证功能结果清晰.
22. 关于编译器:关闭警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[myObj performSelector:mySelector withObject:name];
#pragma clang diagnostic pop
23. 避免循环引用,特别是在block异步回调时,必须用weak-strong,其中最好能if(strongSelf)再继续下面的业务.
__weak typeof(self) weakSelf = self;
__strong typeof(self) strongSelf = weakSelf;
24. 耗时操作应该放在子线程,避免卡主主线程
25. 尽量不要操作图层直接设置圆角,建议采用画图和遮罩来设置圆角
26. 通知,block,代理回调传递规则
1) 除非多视图接受事件处理,否者不采用通知方式,注意通知必须销毁
2) 单个简单事件回调传递,建议block回调,注意采用weak-strong,避免循环引用
3) 如果项目已经定义代理回调,且事件类型多样,参数超过2个,应该采用代理配合枚举,将不同事件聚合共同传递
27. 不要在 init 方法(以及其他初始化方法)里面用 getter 和 setter 方法,应当直接访问实例变量,防止子类重写setter 或 getter 方法
28. 描述BOOL属性 @property(nonatomic, getter = isSelected) BOOL selected;
29. 合理利用懒加载,当实例化一个对象需要耗费很多资源,或者这是需要的时候再调用,我们采用懒加载方法以延迟实例化,而不是在 init 方法里给对象分配内存。
30. 代码块 -> 代码块如果在闭合的圆括号内的话,会返回最后语句的值
NSURL* url = ({
NSString* urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, endpoint];
[NSURL URLWithString: urlString];
});