十分钟让你学会代码(看完这篇你们团队的代码也很规范)
十分钟让你学会代码(看完这篇你们团队的代码也很规范)switch (menuType) { case menuTypeLeft: { // ... break; } case menuTypeRight: { // ... break; } case menuTypeTop: { // ... break; } case menuTypeBottom: { // ... break; } } 类名6.switch 语句后面的 default 分支必须存在,除非是在对枚举进行 switch。- (void)doHomework { if (self.hungry) { return; } if (self.thirsty) { return; } if (self.tired) { return; } papapa.then.over; } 3.每个分支的实现都必须使用 {
一些原则- 长的,描述性的方法和变量命名是好的。不要使用简写,除非是一些大家都知道的场景比如 VIP。不要使用 bgView,推荐使用 backgroundView
- 见名知意。含义清楚,做好不加注释代码自我表述能力强。(前提是代码足够规范)
- 不要过分追求技巧,降低代码可读性
- 删除没必要的代码。比如我们新建一个控制器,里面会有一些不会用到的代码,或者注释起来的代码,如果这些代码不需要,那就删除它,留着偷懒吗?下次需要自己手写
- 在方法内部不要重复计算某个值,适当的情况下可以将计算结果缓存起来
- 尽量减少单例的使用。
- 提供一个统一的数据管理入口,不管是 MVC、MVVM、MVP 模块内提供一个统一的数据管理入口会使得代码变得更容易管理和维护。
- 除了 .m 文件中方法,其他的地方"{"不需要另起一行。
- (void)getGooodsList { // ... } - (void)doHomework { if (self.hungry) { return; } if (self.thirsty) { return; } if (self.tired) { return; } papapa.then.over; }
变量
- 一个变量最好只有一个作用,切勿为了节省代码行数,觉得一个变量可以做多个用途。(单一原则)
- 方法内部如果有局部变量,那么局部变量应该靠近在使用的地方,而不是全部在顶部声明全部的局部变量。
运算符
- 1元运算符和变量之间不需要空格。例如: n
- 2元运算符与变量之间需要空格隔开。例如: containerWidth = 0.3 * Screen_Width
- 当有多个运算符的时候需要使用括号来明确正确的顺序,可读性较好。例如: 2 << (1 2 * 3 - 4)
条件表达式
- 当有条件过多、过长的时候需要换行,为了代码看起来整齐些
//good if (condition1() && condition2() && condition3() && condition4()) { // Do something } //bad if (condition1() && condition2() && condition3() && condition4()) { // Do something }
2.在一个代码块里面有个可能的情况时善于使用 return 来结束异常的情况。
- (void)doHomework { if (self.hungry) { return; } if (self.thirsty) { return; } if (self.tired) { return; } papapa.then.over; }
3.每个分支的实现都必须使用 {} 包含。
// bad if (self.hungry) self.eat() // good if (self.hungry) { self.eat() }
4.条件判断的时候应该是变量在左,条件在右。 if ( currentCursor == 2 ) { //... }
5.switch 语句后面的每个分支都需要用大括号括起来。
6.switch 语句后面的 default 分支必须存在,除非是在对枚举进行 switch。
switch (menuType) { case menuTypeLeft: { // ... break; } case menuTypeRight: { // ... break; } case menuTypeTop: { // ... break; } case menuTypeBottom: { // ... break; } }
类名
- 大写驼峰式命名。每个单词首字母大写。比如「申请记录控制器」ApplyRecordsViewController
- 每个类型的命名以该类型结尾。
- ViewController:使用 ViewController 结尾。例子:ApplyRecordsViewController
- View:使用 View 结尾。例子:分界线:boundaryView
- NSArray:使用 s 结尾。比如商品分类数据源。categories
- UITableViewCell:使用 Cell 结尾。比如 MyProfileCell
- Protocol:使用 Delegate 或者 Datasource 结尾。比如 XQScanViewDelegate
- Tool:工具类
- 代理类:Delegate
- Service 类:Service
类的注释
有时候我们需要为我们创建的类设置一些注释。我们可以在类的下面添加。
枚举
枚举的命名和类的命名相近。
typedef NS_ENUM(NSInteger UIControlContentVerticalAlignment) { UIControlContentVerticalAlignmentCenter = 0 UIControlContentVerticalAlignmentTop = 1 UIControlContentVerticalAlignmentBottom = 2 UIControlContentVerticalAlignmentFill = 3 };
宏
- 全部大写,单词与单词之间用 _ 连接。
- 以 K 开头。后面遵循大写驼峰命名。「不带参数」
#define HOME_PAGE_DID_SCROLL @"com.xq.home.page.tableview.did.scroll" #define KHomePageDidScroll @"com.xq.home.page.tableview.did.scroll"
属性
书写规则,基本上就是 @property 之后空一格,括号,里面的 线程修饰词、内存修饰词、读写修饰词,空一格 类 对象名称 根据不同的场景选择合适的修饰符。
改进
我们知道了平时在使用 Xcode 开发的过程中使用的系统提供的代码块所在的地址和新建控制器、模型、view等的文件模版的存放文件夹地址后,我们就可以设想下我们是否可以定制自己团队风格的控制器模版、是否可以打造和维护自己团队的高频使用的代码块?
答案是可以的。
Xcode 代码块的存放地址:~/Library/Developer/Xcode/UserData/CodeSnippets Xcode 文件模版的存放地址:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/File Templates/
意义
- 为了个人或者团队开发者的代码更加规范。Property的书写的时候的空格、线程修饰词、内存修饰词的先后顺序
- 提供大量可用的代码块,提高开发效率。比如在 Xcode 里面敲 UITableView_init 便可以自动懒加载创建一个 UITabelView 对象,你只需要设置在指定的位置写相应的参数
- 通过一些代码块提高代码规范、避免一些bug。比如曾看到过 block 属性用 strong 修饰的代码,造成内存泄漏。举个例子你在 Xcode 中输入 Property_delegate 就会出来 @property (nonatomic weak) id<<#delegate#>> delegate;,你输入 Property_block 就会出来 @property (nonatomic copy) <#returnType#> (^<#Block#>)(<#parType#>);
代码块的改造
我们可以将属性、控制器生命周期方法、单例构造一个对象的方法、代理方法、block、GCD、UITableView 懒加载、UITableViewCell 注册、UITableView 代理方法的实现、UICollectionVIew 懒加载、UICollectionVIewCell 注册、UICollectionView 的代理方法实现等等组织为 codesnippets
思考
- 封装好 codesnippets 之后团队除了你编写这个项目的人如何使用?如何知道是否有这个代码块?
- 方案:先在团队内召开代码规范会议,大家都统一知道这个事情在。之后大家共同维护 codesnippets。用法见下
- 属性:通过 Property_类型 开头,回车键自动补全。比如 Strong 类型,编写代码通过 Property_Strong 回车键自动补全成如下格式
@property (nonatomic strong) <#Class#> *<#object#>;
- 方法:以 Method_关键词 回车键确认,自动补全。比如 Method_UIScrollViewDelegate 回车键自动补全成 如下格式
#pragma mark - UIScrollViewDelegate - (void)scrollViewDidScroll:(UIScrollView *)scrollView { }
- 各种常见的 Mark:以 Mark_关键词 回车确认,自动补全。比如 Method_MethodsGroup 回车键自动补全成 如下格式
#pragma mark - life cycle #pragma mark - public Method #pragma mark - private method #pragma mark - event response #pragma mark - UITableViewDelegate #pragma mark - UITableViewDataSource #pragma mark - getters and setters
- 封装好 codesnippets 之后团队内如何统一?想到一个方案,可以将团队内的 codesnippets 共享到 git,团队内的其他成员再从云端拉取同步。这样的话团队内的每个成员都可以使用最新的 codesnippets 来编码。
- 编写 shell 脚本。几个关键步骤:
- 给系统文件夹授权
- 在脚本所在文件夹新建存放代码块的文件夹
- 将系统文件夹下面的代码块复制到步骤2创建的文件夹下面
- 将当前的所有文件提交到 Git 仓库
文件模版的改造
我们观察系统文件模版的特点,和在 Xcode 新建文件模版对应。
所以我们新建 Custom 文件夹,将系统 Source 文件夹下面的 Cocoa Touch Class.xctemplate 复制到 Custom 文件夹下。重命名为我们需要的名字,我这里以“Power”为例
进入 PowerViewController.xctemplate/PowerViewControllerObjective-C
修改 ___FILEBASENAME___.h 和 ___FILEBASENAME___.m 文件内容
在替换 .h 文件内容的时候后面改为 UIViewController,不然其他开发者新建文件模版的时候出现的不是 UIViewController 而是我们的 PowerViewController
修改 TemplateInfo.plist
思考:
- 如何使用
- 商量好一个标识(“Power”)。比如我新建了单例、控制器、Model、UIView4个模版,都以为 Power 开头。
如何共享
以 shell 脚本为工具。使用脚本将 git 云端的代码模版同步到本地 Xcode 文件夹对应的位置就可以使用了。关键步骤:
- git clone 代码到脚本所在文件夹
- 进入存放 codesnippets 的文件夹将内容复制到系统存放 codesnippets 的地方
- 进入存放 file template 的文件夹将内容复制到系统存放 file template 的地方
- Property 属性。敲 Property_ 自动联想,光标移动选中后敲回车自动补全
- Mark 标识。 敲 Mark_ 自动联想,会展示各种常用的 Mark,光标移动选中后敲回车自动补全
- Method 方法。敲 Method_ 自动联想,会展示各种常用的 Method,光标移动选中后敲回车自动补全
- GCD。敲 GCD_ 自动联想,会展示各种常用的 GCD,光标移动选中后敲回车自动补全
- 常用 UI 控件的懒加载。敲 _init 自动联想,展示常用的 UI 控件的懒加载,光标移动选中后敲回车自动补全
- Delegate。敲 Delegate_ 自动联想,会展示各种常用的 Delegate,光标移动选中后敲回车自动补全
- Notification。敲 NSNotification_ 自动联想,会展示各种常用的 NSNotification 的代码块,比如发送通知、添加观察者、移除观察者、观察者方法的实现等等,光标移动选中后敲回车自动补全
- Protocol。敲 Protocol_ 自动联想,会展示各种常用的 Protocol 的代码块,光标移动选中后敲回车自动补全
- 内存修饰代码块
- 工程常用 TODO、FIXME、Mark。敲 Mark_ 自动联想,会展示各种常用的 Mark 的代码块,光标移动选中后敲回车自动补全
- 内存修饰代码块。敲 Memory_ 自动联想,会展示各种常用的内存修饰的代码块,光标移动选中后敲回车自动补全
- 一些常用的代码块。敲 Thread_ 等自动联想,选中后敲回车自动补全。
chmod x ./syncSnippets.sh // 为脚本设置可执行权限 chmod x ./uploadMySnippets.sh // 为脚本设置可执行权限 ./syncSnippets.sh // 同步git云端代码块和文件模版到本地 ./uploadMySnippets.sh //将本地的代码块和文件模版同步到云端