我的代码习惯
一直以来我都坚持团队合作里面要有一份编码规范,尽量保持编码的一致性,让代码更清晰,便于代码审查和团队合作。即使迫于某些原因无法普遍的实施,但也要严格要求自己。
自己写的代码不仅仅是对项目,对自己负责,也要对他人负责。正常来讲在自己的写的东西在特定阶段会有其他人参与,也会被其他人接手,为了不被后来人骂的太惨,还是要保持良好的编码习惯。
代码规范
代码规范不是自己凭空想像的,主要还是参考了各家的代码规范,外加自己的实践。自己遵守的代码规范,主要参考Objc Zen Book。当时在火车上一口气看完,看完即决定就是它了。之前已有整理,详见《禅与Objective-C 编程艺术》笔记。接下来我再挑一些比较重要的来讲。
代码组织
分组
- 推荐使用属性。除了
init
和dealloc
方法,应该总是使用.
语法访问属性,如果getter
方法里进行了初始化和其他操作,init
方法里也应该使用.
语法。 - 善于用
#Pragma Mark
进行代码分组。 - 私有方法添加
p_
前缀进行区分,但不要以下划线_
开头。
[站外图片上传中...(image-253e0f-1533479745573)]
这样分组主要依据是涉及逻辑和经常变化的部分越靠前。ConfigViews
和Init
部分属于配置和布局,一个很少更改,二是手动布局代码量可能会很多,因此放到最后。这样我们在查看.m
文件是更多的去关心这部分的业务逻辑。
语句总是使用大括号包围,以避免错误
推荐
if (!error) {
return success;
}
不推荐
if (!error)
return success;
或者
if (!error) return success;
nil和BOOL检查使用感叹号!
来判断
因为nil
是解释到NO
所以没必要在条件语句里面把它和其他值比较。同时,不要直接把它和YES
比较,因为YES
的定义是1
而BOOL
是8位的,实际上是char
类型。
推荐
if (someObject) { ...
if (![someObject boolValue]) { ...
if (!someObject) { ...
不推荐
if (someObject == YES) { ... // Wrong
if (myRawValue == YES) { ... // Never do this.
if ([someObject boolValue] == NO) { ...
三元运算符?:
,应该只用在它能让代码更加清晰的地方
推荐
result = a > b ? x : y;
result = object ? : [self createObject]; // 第二个参数返回和条件语句中已经检查的对象一致时
不推荐
result = a > b ? x = c > d ? c : d : y;
result = object ? object : [self createObject]; // 第二个参数返回和条件语句中已经检查的对象一致时
当switch语句里使用可枚举的变量的时候,default
是不必要的,没有default
有利于错误的排查
switch (menuType) {
case ZOCEnumNone:
// ...
break;
case ZOCEnumValue1:
// ...
break;
case ZOCEnumValue2:
// ...
break;
}
关于遍历
多用快速遍历(for in)或者block的方式遍历,少用常规for循环。
Enumerated Types枚举类型
- 推荐使用
NS_ENUM()
声明。 - 用枚举表示状态,选项,状态码,可读性和可用性会大大增加。
常量
- 多用类型常量,少用
#define
预处理指令,有利于错误检测。 - 类型常量如果在类外可见,则应该在.h文件中使用
extern
声明。
命名
- 使用驼峰命名法
- 单词直接不使用
_
连接。 - 多个参数时使用描述性关键词,不使用
and
等连接词来表明多个参数。
多使用字面量来创建不可变的实例对象。
推荐
NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;
注释
秉承好的代码不需要注释来规范命名。但是一下几点推荐注释。
- .h 头文件中推荐声明该类的作用
- 接口方法应该有注释
- 如果变量或方法名不明确的应该加上注释
- 待完善部分申明
TODO:
- 在需要的地方使用
#warning
和#error
提示
美化代码
-
方法的大括号和其他的大括号(if/else/switch/while 等) 总是在同一行开始,在新起一行结束。
推荐:
if (user.isHappy) { //Do something } else { //Do something else }
不推荐:
if (user.isHappy) { //Do something } else { //Do something else }
方法命名在方法类型(-/+符号)后应该有一个空格。
方法之间应该要有一个空行来帮助代码看起来清晰且有组织。 方法内的空格应该用来分离功能,但是通常不同的功能应该用新的方法来定义。
优先使用
auto-synthesize
。但是如果必要的话,@synthesize
and@dynamic
。-
应该总是让冒号对齐。有一些方法签名可能超过三个冒号,用冒号对齐可以让代码更具有可读性。即使有代码块存在,也应该用冒号对齐方法。
推荐:
[UIView animateWithDuration:1.0 animations:^{ // something } completion:^(BOOL finished) { // something }];
接口设计
- 类加上前缀,避免命名空间冲突。
- 类的头文件(.h)中尽量少引入其他头文件,避免互相引用,降低耦合,减少编译时间。如需引入类,使用前向声明(
@class
) - 尽量创建不可变对象,不要把可变对象属性公开,而是提供相关方法。
- 属性如果有读写权限设定,需要用
readonly
声明 - 方法命名要清晰,尽量不使用缩略词
善用代码片段
Xcode原生带有一些系统的
Code Snippet
,我们也可以根据需要添加我们自己的代码片段,提高开发效率。创建的代码片段会生成一个个文件,因此我们可以同步到云端,在不同设备上共享。
使用Assets管理图片
- slicing
- render
结合其他工具使用,提高效率
- vscode
- SourceTree
- Go2Shell
- iTerm2
- simsim
- Sequel Pro
- AppCode