一些原则 摘记--知识小集https://mp.weixin.qq.com/s/D2a_refSr3tsHuAEgMtKQw
- 长的,描述性的方法和变量名是好的。
- 不要过分追求技巧,降低代码可读性。
- 删除没必要的代码。如果这些代码不需要, 那就删除它,留着偷懒吗? 下次需要自己手写。
- 尽量减少单例使用。
变量
- 一个变量最好只有一个作用,切勿为了节省代码行数,觉得一个变量可以做多个用途。(单一原则)
- 方法内部如果有局部变量,那么局部变量应该靠近在使用的地方,而不是全部在顶部声明全部的局部变量。
- (Swift)private全局变量放置一块, public变量放置一块。
运算符
- 1元运算符和变量之间不需要空格。 例如:
++n
。 - 2元运算符与变量之间需要空格隔开。例如:
tempWidth = 0.3 * MSFCommon.ScreenW
- 当有多个运算符的时候需要使用括号来明确正确的顺序,可读性比较好。 例如:
5 << (10 + 2 * 5 - 5)
条件表达式
- 当有条件过多、过长的时候需要换行
//good
if (condition1() &&
condition2() &&
condition3()) {
//TODO
}
//bad
if (condition1() && condition2() && condition3()) {
//TODO
}
- 在一个代码块里面有个可能的情况时,善于使用return来结束异常的情况。
- (void)doHomework {
if (self.hungry) {
return;
}
if (self.thirsty) {
return;
}
//TODO
}
- 每个分支的实现必须使用 {} 包含
// good
if (self.hungry) {
self.eat()
}
//bad
if (self.hungry) self.eat()
- 条件判断的时候应该是变量在左,条件在右。
if (index == 2) { //...}
- switch 语句后面的每个分支都需要用
大括号
括起来。
属性
书写规则, 基本上就是 @property 之后空一格, 括号, 里面的 线程修饰词、内存修饰词、读写修饰词, 空一格 类 对象名称
@property (nonatomic, assign, readonly) BOOL loading;
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, weak) id<#delegate#> delegate;
私有变量
推荐以 —
开头, 写在 .m 文件中。 列如 NSString *_somePrivateVariable
单例
单例适合全局管理状态或者事件的场景。 一旦创建,对象的指针保存在静态区, 单例对象在堆区内存中分配的内存空间只有程序销毁的时候才会释放。基于这种特点,那么我们类似UIApplication对象,需要全局访问唯一一个对象的情况才适合单例, 或者访问频次较高的情况,我们的功能模块的生命周期肯定小于App的生命周期,如果多个单例对象的话, 势必App的开销会很大, 槽糕的情况系统会杀死App。 如果觉得非要单例比较好,那么注意需要在合适的场合tearDown掉。
单例的使用场景如下:
- 控制资源的使用, 通过线程同步来控制资源的并发访问。
- 控制实例的产生,以达到节约资源的目的。
- 控制数据的共享,在不建立直接关联的条件下, 让多个不相关的进程或进程之间实现通信。
一、命名规范
- 参数命名为驼峰命名法。
- 属性名、变量名、类名、方法名命名见名知意, 含义清楚,最好不加注释代码自我表述能力强。
UI控件 | 命名方式 |
---|---|
UIButton | xxxBtn |
UIImage | xxxImage |
UIImageView | xxxImageView |
UILabel | xxxLabel |
UITextField | xxxTF |
UITextView | xxxTextView |
View | 命名方式 MSF为项目前缀 |
---|---|
UIView | MSFxxxView |
UIScrollView | MSFxxxScrollView |
UITableView | MSFxxxTableView |
UICollectionView | MSFxxxCollectionView |
UITableViewCell | MSFxxxCell |
UICollectionViewCell | MSFxxxCollectionCell |
UIPickerView | MSFxxxPickerView |
UIProgressView | MSFxxxProgressView |
Model | 命名方式 MSF为项目前缀 |
---|---|
model | MSFxxxModel |
viewModel | MSFxxxVM |
ViewController | 命名方式 MSF为项目前缀 |
---|---|
UIViewController | MSFxxxVC |
其他 | 命名方式 MSF为项目前缀 |
---|---|
delegate | MSF类名Delegate |
工具 | MSFxxxTool |
管理 | MSFxxxMagager |
service | MSFxxxService |
layout | MSFxxxLayout |
helper | MSFxxxHelper |
二、控制器层代码
// MARK -- life Cycle
1. viewWillAppear。
2. viewDidAppear。
3. viewWillDisAppear。
4. viewDidDisAppear。
5. viewDidLoad。
MARK -- override method
MARK -- 配置导航栏。
MARK -- 设置通知
MARK -- Load Data
MARK -- setUp UI
MARK -- UITableViewDelegate
MARK -- public method、Action
MARK -- private method、Action
MARK -- lazy (getter / setter)
dealloc / deinit。
注:
一、控制器中的自定义View、UITableView、UICollectionView尽量通过懒加载方式设置。
三、View层代码
1. init
2. 设置UI。
3. 设置UI数据。
3. 设置控件点击事件Action。
4. 懒加载控件。
注:
1.用#pragma mark 注释分割开
2.将控件lazy放在最后是为了视图控件比较多的情况。
四、Model层代码
设置model变量 + 注释变量含义
五、ViewModel层代码
1.加载处理数据。
2.高度计算。
六、OC中
- 宏、静态变量:
- 全大写,单词间用
_
分割; #define UP_DATA "UP_DATA" - K开头驼峰命名; #define KUpdateData "KUpdateData"
- 枚举类型统一使用typedef NS_ENUM(类型, 名称)
- 当用到位掩码时,使用NS_OPTIONS宏
- 代理属性用weak修饰。
- 方法名和
-
空格间隔。 - 资源图片采用Assets.xcassets管理,图片命名采用:模块_xxx_xxx.png
- 采用字面量创建数组、字典、NSNumber:
NSArray *array = @[@"liLei", @"zhangSan"]
NSDictionary *dic = @{@"key": @"value"}
NSNumber *number = @2
- 访问CGRect的x、y、width、height时,使用CGGeometry函数代替直接访问结构体成员。
CGRect frame = self.view.frame;
CGFloat x = CGRectGetMinX(frame)
CGFloat width = CGRectGetWidth(frame)
- 布尔,因为nil解析为NO,永远不要直接和YES进行比较,YES被定义为1,而BOOL可以多达8位。
good: if(!someObject) {},
if(isSomeObject) {}
bad: if(someObject == NO/nil) {}, if(isSomeObject == YES)
七、注释
- 类文件要加注释,表明含义。
- 自定义的方法需要写出功能注释。
- 比较大的代码块需要写出关键注释。
- 代码中出现的阿拉伯数字的地方需要写出注释。
- 逻辑处理代码的地方要写出关键注释。
- 容易产生歧义的代码写出注释。
- 对于 .h文件中方法的注释,一律按快捷键 cmd+option+/ 三个快捷键解决。按需在旁边对方法进行说明解释、返回值、参数的说明和解释。
八、方法
方法名 | 含义 |
---|---|
initXXX | 初始化方法 |
isXXX | 返回bool类型使用is作为前缀 |
XXX | 返回的内容为名称 |
setXXX | 设置某个属性或者相关数据 |
updateXXX | 更新数据 |
saveXXX | 保存数据 |
clearXXX | 清除数据 |
drawXXX | 绘制相关 |
onXXX | 响应事件 |
setupUI | 添加视图 |
loadData | 加载数据 |
loadMoreData | 加载更多数据 |
- 每个方法之间空一行。
- 方法中参数不要用and连接。
- 可以使用情景动词can、should、will进一步说明意思,但是不要使用do或者does。
- 如果方法参数过多过长,建议多行书写。 用冒号进行对齐。
- 一个函数只做一个事情,做到单一原则。所有的类、方法设计好后就可以类似搭积木一样实现一个系统。
- 一个方法内的代码最好保持在50行以内。
- 多个函数如果有逻辑重复的代码,建议将重复的部分抽取出来, 成为独立的函数进行调用。
- 函数如果有多个参数,外部传入的参数需要检验参数的非空、数据类型的合法性, 参数错误做一些措施:立即返回、断言。
- (void)doHomework:(NSString *)name
period:(NSInteger)second
score:(NSInteger)score {
}
good:
- (CGSize)cellSize;
- (BOOL)canHide;
- (BOOL)shouldClose;
bad:
- (CGSize)getCellSize;
- (void)doesAcceptInfo;
九、版本更新
版本号说明 | 实例 | 备注 |
---|---|---|
A.b.c | 1.2.2->2.0.0 | 属于重大功能更新:添加新的业务模块等 |
a.B.c | 1.2.2->1.3.0 | 属于小部分内容更新:已有业务模块的新增小业务等 |
a.b.C | 1.2.2->1.2.3 | 属于补丁内容更新:bug修复,代码优化等 |
十、补充,未完待续
1.未完成或者需要优化的代码块,记得加上TODO注释。
2.针对多种情况,采用枚举适配。
网友评论