Objective-C代码规范
最近感觉自己老了,一直呆在小公司,感觉到了疲惫与苦涩,虽然并没有如老板所想已达到瓶颈,依然感觉还有好多东西可学和想学,不过我的前面的确是有一堵无形的墙在挡住我前行的脚步,我希望自己能够停下来,静下心来,对自己的以往的工作进行总结和反思, 所以期望写一系列的文章来总结总结自己的经验,反思自己,希望在反思中有进一步的提高!!
这一篇总结一位老码农几年编码的所思所想所感, 讲述代码规范的同时也解释为啥要这么干
-
为什么要有代码规范
代码规范的目的是"读",给N久之后的自己, 给其他人读, 试想过了半年之后,你再看代码, 你是否能很快就看懂自己曾经写过的程序呢?我觉得维护过别人写的代码的人都能明白这个问题.
-
陷阱和错误
- 使用前缀
比如项目名称叫做TaoBao,则前缀为TB, 前缀的意义在于避免冲突,特别是与第三方代码的冲突,以前经常碰到这种坑,某些恶心的第三方库竟然前缀都不加就满世界的发布,特别是一些基础类,如Base64.h
- 条件陷阱
这个藏得有些深,经常会犯错,具体如
<pre>if (v1 = 1) { // 判断V1是否等于1 }
</pre>这段代码本意是判断v1是否等于1,结果v1被赋值为1了,并且因为赋值得到的结果是True,所以if 代码块也会被执行
针对这种情况,一般判断采用反写,如下代码,如果写错,立马报错就可以改过来了
<pre>if (1 = v1) { // 判断V1是否等于1,错误会立即报错 }
</pre> - 魔法数字
这个也是挺恶心的, 经常会碰到这样的代码
<pre>int result = v1 + 7788
</pre>从始至终没有解释下7788是什么? 这就是魔法数字, 为了避免这种情况, 将某些常量命名,
<pre>#define TBBeginTagOfCovers 7788 int result = v1 + TBBeginTagOfCovers
</pre>
-
怎样让代码整洁
-
类命名
- 类名具有意义,能够一眼就知道干嘛的
- 首字母大写
- 骆驼文
类的命名主要有以上三个规则, 举例如下,如一个查看图片预览的视图控制器, 则命名为 ImagePreviewController, 首字母i大写, ImagePreview交代目的, Controller告知这是一个控制器.(如果你不知道神马是骆驼文, 那我就瞪着眼的告诉你骆驼文就像驼峰一样,如AppleTree,一高一低快速区分单词)
-
变量\常量
常量通俗用法是首字母大写, 骆驼文写法,如 int MaxSectionNumber;
变量首字母小写, 骆驼文写法, 如usernameField, nameLabel, 这种命名有助于理解用途,usename表示用户名,field表示可以输入区域,nameLabel表示名称,label表示这是一个UILabel -
方法
方法用的比较讲究一点,具体例子如下,首先名称名要指明方法的用途,其次,格式"-空格(返回值)方法名:(类型)参数名空格{换行}"
<pre>- (void)doSth:(NSString *)paramName {// -之后是一个空格,尾部{之前有个空格 // do sth }
</pre> -
注释,
Objective-C支持两种注释
<pre>// 注释一行代码,注意注释正文和斜杆间留一个空格(为了更优美的阅读体验) /* 多行注释, 包括在/* 和*/之间都是注释内容 */
</pre>-
注释常量\变量
我一般建议对变量(常量)的注释添加在其后面, 这样有助于相似属性摆在一起, 相比于"注释一行,变量一行"的做法阅读起来更顺, 末尾有强迫症的可以对齐
<pre>// 广告类型 extern NSString *const RE_AD_TYPE_PRODUCT; //产品 extern NSString *const RE_AD_TYPE_EXHIBITOR; //展商 extern NSString *const RE_AD_TYPE_SESSION; //会议
</pre>这种方式是不是比下面的看起来更好看一些呢?
<pre>//产品 extern NSString *const RE_AD_TYPE_PRODUCT; //展商 extern NSString *const RE_AD_TYPE_EXHIBITOR; //会议 extern NSString *const RE_AD_TYPE_SESSION;
</pre> -
注释方法
注释方法 简单方法采用单行注释,说明方法用途即可,如果方法名够清晰,则不要使用注释
写法见下图, 内容与*间留一个空格, 不同的内容间留空行, 顶部写方法的用途,可以一行或多行,看需要,这里可以讲明下方法的思路,一些逻辑的说明,@param则解释参数的类型,用途,如果有多个候选,则讲明每个候选的意义
这里举个失败的例子,如代码更新了,但是注释未更新,或者注释不明确
失败注释及修正方法 -
注释过程
我很喜欢下面的写法, 在动笔写代码前先将明确逻辑, 然后才是按照步骤完成代码
注释过程
-
-
代码组织
- 通过
#pragma mark -
分隔代码块
这个用法有两种,一种是带横线的(mark后面带横线), 一种是不带横线的(mark后面不带横线), 如下图所示, 带横线可以将模块区分, 不带横线可以对模块内区分,这个建议多用, 有助于代码整洁
pragma mark 用法 - BadSmell(KentBeck提出的概念), 当你看到一段代码在不同的地方多次出现的时候,你就应该嗅出坏味, 然后将其抽出来在多个地方调用,而不是导出copy paste.
-
灵活使用getter
这是最近学到的一招, 为了让代码更加优美, 将初始放入getter中, 这样在真正使用的时候专注配置就好了
getter的使用 - UIViewController模板
感谢 @mastertsx @十一岁的加重,
我总结了一个UIViewController的模板,有兴趣的童鞋可以将它加为一个snippets, 以后新的controller就不用每次都重复机械运动了(有建议或者意见请留言),地址是UIViewControllerTemplate
- 通过
-
怎样让逻辑通顺
- 写代码前整理思路, 确定实现方案再动手
- 多写工具类, 将功能抽调成工具类, 真正使用者只是使用工具, 而工具可复用
- 多看, 多思, 多实践