最全最详细的注释使用说明

最全最详细的注释使用说明

[TOC]

前言

  • 好的代码本身就是一种注释
  • 代码的可读性更重要

注释的作用

代码的意义,除了完成功能业务这一最基本的要求之外,最终还要让别人能够读懂你的代码,让别人看得懂这段逻辑的意义,让别人更快更准确的理解这个方法的使用规则,同时使代码层级分明,方便快速浏览,以及生成使用文档等等。总之就是方便自己与他人后期维护。尤其是多人维护同一个项目的时候,注释的意义不言而喻,注释到位,别人去维护你写的代码时,就不会那么频繁的问你,甚至背后问候你了~~~

常用的注释分类

个人理解,对于注释的分类,从宏观功能上划分,可以分为 代码注释 和 特殊功能注释。
代码注释又可以从位置特点上细分,可以分为单行注释,行尾注释(多用于属性、枚举值),多行注释(方法,协议,类等)。
下面我将从刚刚说的几个维度去介绍。

环境介绍

  • demo日期:2019.1.1
  • macOS 10.14.1
  • Xcode 10.1
  • 示例代码语言:Objective-C

代码注释

需要写代码注释的地方非常多,包括不限于以下场景:文件的注释、类的注释、一段代码逻辑的说明;属性、枚举、方法、block等声明的注释

单行注释

最常见的就是这下面这样样式:

示例代码:

/* 这个方法的功能是做这个事情的,要注意呀~ */
+ (void)method {
    // 这里逻辑是这样的,要注意呀~
    [self new];
}

/// 单行注释10
@property (nonatomic, copy) NSString *str10;
//! 单行注释11
@property (nonatomic, copy) NSString *str11;
/** 单行注释12-可用于多行 */
@property (nonatomic, copy) NSString *str12;
/*! 单行注释13-可用于多行 */
@property (nonatomic, copy) NSString *str13;

上面两种注释方法,都是最最常见的普通注释的写法,两种写法但凡是写注释的地方都能用上,能够满足注释最基本的提示功能,没有什么特别要说明的。不过有一个缺陷是不会有 [option + 单击] 时Xcode的注释提示,所以和下面的单行注释分开说。

使用场景大多是代码块中,对于一些逻辑关键的的描述。另外,个人比较喜欢前后都加上一个空格的写法。

后面四种写法无论是否加空格,使用上都没有区别,都会有Xcode补全时的提示,以及 [option + 单击] 时的提示。

总之,单行注释适合无入参逻辑简单的 类、方法、block 等的注释。
也可以用于属性或枚举的注释,不过,属性枚举注释个人认为更适合用行尾注释。

行尾注释

行尾最大的特点,就是在三个注释符号加上一个<小于号紧密的凑在一起。

示例代码:

@property (nonatomic, copy) NSString *str20; ///< 行尾注释20
@property (nonatomic, copy) NSString *str21; //!< 行尾注释21
@property (nonatomic, copy) NSString *str22; /**< 行尾注释22 */
@property (nonatomic, copy) NSString *str23; /*!< 行尾注释23 */

个人觉得行尾注释使用场景最多在于属性的声明和枚举值定义,这时候这么写一行就展示的下,屏幕大的时候看代码清晰明了。

有几个注意点(对于属性和枚举):

  • 所有上述写法,无论是否带空格,无论是在.h或.m中,Xcode代码补全时会有提示
  • 在.h中,四种写法都能 [option + 单击] 显示方法注释
  • 在.m中,只有 [///<不带空格] 这种注释写法点击才会显示注释

也就是说,[///<不带空格] 这种注释写法是最简单有效的行尾注释写法。不过,我总觉得不带空格总是不够优雅~

行尾注释不能适用于单行注释,否则和最最普通的注释无差别。

另外,如果属性含义过于复杂,尤其是存在多种状态时,可以使用多行注释的写法。

多行注释

示例代码:

手动写的样式:
/**
 *  方法注释test02
 */
- (void)test02 {}
/*!
 *  方法注释test03
 */
- (void)test03 {}
Xcode生成的样式:
/**
 这是一个多参数的方法
 
 @param count   参数0,数量
 @param str     参数1,字符串
 @param objc    参数2,对象
 @return        返回值,返回值bool情况说明
 */
- (BOOL)testC0WithCount:(NSUInteger)count str:(NSString *)str objc:(id)objc {
    return YES;
}

效果如图:


方法option提示-01.png

上面两种没有什么好说了,具体就是看个人喜好与团队风格了。下面说一下各个关键字的使用。

参数list:

注释中常用的标签:

关键字 说明
@brief 使用它来写一段你正在文档化的method, PRoperty, class, file, struct, 或enum的短描述信息。
@discusstion 用它来写一段详尽的描述。如果需要你可以添加换行。
@param 通过它你可以描述一个 method 或 function的参数信息。你可以使用多个这种标签。
@return 用它来制定一个 method 或 function的返回值。
@note 注意点,补充说明
@see 用它来指明其他相关的 method 或 function。你可以使用多个这种标签。
@sa 同上
@code 使用这个标签,你可以在文档当中嵌入代码段。当在Help Inspector当中查看文档时,代码通过在一个特别的盒子中用一种不同的字体来展示。始终记住在写的代码结尾处使用@endcode标签。
@remark 在写文档时,用它来强调任何关于代码的特殊之处。

/**
 *  各种关键字的使用示例

 @brief 使用它来写一段你正在文档化的method, PRoperty, class, file, struct, 或enum的短描述信息。
 @discusstion 参数用它来写一段详尽的描述。如果需要你可以添加换行。
 我换两行试试
 第三行呢?
 
 
 @param str 参数
 @return        返回值,返回值bool情况说明

 @note 注意点,补充说明

 @see - (BOOL)testC0WithCount:(NSUInteger)count str:(NSString *)str objc:(id)objc{}
 @sa 同上

 @code
    使用这个标签,你可以在文档当中嵌入代码段。当在Help Inspector当中查看文档时,代码通过在一个特别的盒子中用一种不同的字体来展示。始终记住在写的代码结尾处使用标签
    // 方法
     - (void)testb0 {
        NSLog(@"注释标签");
     }
 @endcode
 
 @remark 在写文档时,用它来强调任何关于代码的特殊之处。
 
 *  其他注释
 */
- (BOOL)testC1WithParam:(NSString *)str {
    return NO;
}

效果如图:


方法option提示-02.png

附加:

记录文件常用标签:

关键字 说明
@file 使用这个标签来指出你正在记录一个文件(header 文件或不是)。如果你将使用Doxygen来输出文档,那么你最好在这个标签后面紧接着写上文件名字。它是一个top level 标签。
@header 跟上面的类似,但是是在 HeaderDoc中使用。当你不使用 Doxygen时,不要使用上面的标签。
@author 用它来写下这个文件的创建者信息
@copyright 添加版权信息
@version 用它来写下这个文件的当前版本。如果在工程生命周期中版本信息有影响时这会很重要。
@class 用它来指定一个class的注释文档块的开头。它是一个top level标签,在它后面应该给出class名字
@interface 同上
@protocol 同上两个一样,只是针对protocols
@superclass 当前class的superclass
@classdesign 用这个标签来指出你为当前class使用的任何特殊设计模式(例如,你可以提到这个class是不是单例模式或者类似其它的模式)。
@coclass 与当前class合作的另外一个class的名字。
@helps 当前class帮助的class的名字。
@helper 帮助当前class的class名字。

特殊功能注释

特殊功能注释展示效果通常都是在类的方法list中,也就是 [ctrl + 6] 快捷键显示的方法列表。

Pragma mark

这个通常用于一类方法的归纳

示例代码:

#pragma mark - Life Cycle
- (void)viewDidLoad {
    [super viewDidLoad];
}

#pragma mark - Delegate
#pragma mark UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    return nil;
}

#pragma mark UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
}

#pragma mark - Event Response

#pragma mark - Getters UI

效果如图:


方法列表-01.png

可以看到,通过 pragma mark 使用,可以让方法分门别类,快速定位。

使用的注意点:

  • pragma mark 和 pragma mark - 都算是关键匹配对象,不可少打或改变大小写,
  • 对于pragma mark,mark后面只要不是字母,就都可以正常识别。
  • 对于pragma mark - ,中划线前后都一定有空格,在代码列表中,会在其文字描述的上方显示一个分割线

注释标签

标签的功能类似于Pragma mark,会在类的方法列表中展示对应的提示文案和特定icon,支持的有以下几种注释标签。

  • MARK: 文本内容,等同于#pragma mark
  • TODO: 文本内容,等待实现的功能
  • FIXME: 文本内容,需要修正的功能
  • !!!: 文本内容,需要改进的功能
  • ???: 文本内容,有疑问的功能

代码示例:

/**
 *  *** 打印一句话我要用好多代码注释标签 ***
 *  MARK:   等同于#pragma mark
 *  TODO:   等待实现的功能
 *  FIXME:  需要修正的功能
 *  !!!:    需要改进的功能
 *  ???:    有疑问的功能
 
 *  另外,可以加上特定前缀方便检索,效果依旧不变
 *  ET_TODO:   等待实现的功能
 */
NSLog(@"注释标签");

效果如图:


标记注释-01.png

说明点:

  • 五种提示都是关键字符串匹配,大小写和冒号都不能错
  • 基于上面一点,可以自定义特定前缀,方便检索(一堆TODO: !!!: 的项目还是很感人的)

这个可是说是本人最喜欢的功能了,尤其是在代码中要特别强调说明一些事情时。

warming

这个没有什么过多说的,其实在使用好各种标签后,完全没有必要使用warming去产生一个让人烦恼的黄色标志。

示例代码:

#warning 这里是代码warming
#warning code warming

效果如图:


warning-01.png

但是需要注意的一点是,warning对于中文支持是存在问题的,我测试发现所有中文都不展示,且第一个单词的首写字母一定会被大写展示。

attribute

__attribute__表示属性,是Clang(GNU C)提供的一种源码注释,
方便开发者向编译器表达诉求,一般以__attribute__(*)的方式出现在代码中。
为了方便使用,一些常用属性被定义成了宏,经常出现在系统头文件中。
比如NS_CLASS_AVAILABLE_IOS(9_0) 就是 __attribute__(availability(9.0)) 
这个属性的简单写法。
下面介绍一些可能会频繁使用到的属性
iOS-Foundation使用
attribute-iOSFoundation01.png
AFNetworking使用
attribute-AFN01.png
SDWebImage使用
attribute-SD01.png

对于中attribute函数属性

  • 函数属性(Function Attribute)
    • noreturn
    • noinline
    • always_inline
    • pure
    • const
    • nothrow
    • sentinel
    • format
    • format_arg
    • no_instrument_function
    • section
    • constructor
    • destructor
    • used
    • unused
    • deprecated
    • weak
    • malloc
    • alias
    • warn_unused_result
    • nonnull
  • 类型属性(Type Attributes)
    • aligned
    • packed
    • transparent_union,
    • unused,
    • deprecated
    • may_alias
  • 变量属性(Variable Attribute)
    • aligned
    • packed
  • Clang特有的
    • availability
    • overloadable

高级应用-生成注解

ET_TODO:下期

注释的使用

主要使用快捷键

  • cmd + / 快速注释选中行的代码 (单行或者多行)
  • command + Option + /,快速高级的逻辑注释(常用于方法)
  • option + 单击 显示注释指示内容
  • 使用多行注释一段逻辑 /* */,多行注释不可嵌套多行注释

代码片段

Xcode的代码片段(Code Snippets)可以用来自定义代码块,方便快速开发

示例代码:

@property (nonatomic,strong) <#Class#> *<#object#>; ///< <#note#>

关键写法: <#这里是默认提示的文本#>

代码片段-00.png
  • 添加方式步骤1
代码片段-01.png
步骤1图中关键说明
关键字 含义
Title 为你设置的代码短的标题
Summary 方法片段摘要说明
Completion Shortcut 为你设置的快捷代码,当你在Xcode中输入你设置的快捷代码就会出现改代码段
Completion Scopes 为你需要设置的启动作用域,如某些方法内就不能启动快捷代码段
  • 添加方式步骤2
代码片段-02.png
  • 添加方式步骤3(后续修改查看)
代码片段-03.png

生成文档

docxygen 感觉是这 3 个工具中支持语言最多的,可以配置的地方也比较多。我大概看了一下文档,觉得还是比较复杂,而且默认生成的风格与苹果的风格不一致。就去看后面 2 个工具的介绍了。另外,它虽然是开源软件,但是没有将源码放到 github 上让我感觉这个工具的开发活跃度是不是不够。

  • headerdoc

headerdoc 是 Xcode 自带的文档生成工具。在安装完 Xcode 后,就可以用命令行:headdoc2html + 源文件名 来生成对应的文档。我个人试用了一下,还是比较方便的,不过 headerdoc 的注释生成规则比较特别,只生成以 /*! */ 的格式的注释。还有一个缺点是每个类文件对应一个注释文件,没有汇总的文件,这点感觉有点不爽。

  • appledoc

appledoc 是在 stackoverflow 上被大家推荐的一个注释工具。有几个原因造成我比较喜欢它:
它默认生成的文档风格和苹果的官方文档是一致的,而 doxygen 需要另外配置。
appledoc 就是用 objective-c 生成的,必要的时候调试和改动也比较方便。
可以生成 docset,并且集成到 Xcode 中。这一点是很赞的,相当于在源码中按住 option 再单击就可以调出相应方法的帮助。
appledoc 源码在 github 上,而 doxygen 在 svn 上。我个人比较偏激地认为比较活跃的开源项目都应该在 github 上。
相对于 headerdoc,它没有特殊的注释要求,可以用 /** */ 的格式,也可以兼容 /*! */ 的格式的注释,并且生成的注释有汇总页面。

以下步骤主要参考该篇博客, https://blog.csdn.net/xborong/article/details/85057696 </p>
appledoc-官方博客
appledoc-ibireme博客
appledoc-唐巧博客
的博客中的过程都有点问题

appledoc version: 2.2.1 (build 1334)

工具安装

git clone git://github.com/tomaz/appledoc.git
cd ./appledoc
sudo sh install-appledoc.sh

脚本编写

#!/bin/bash
appledoc \
--output ./Doc \
-i *.m \
--project-name "IGUIKit" \
--project-company "Tencent" \
--no-create-docset \
--keep-undocumented-objects \
--keep-undocumented-members \
--no-warn-undocumented-object \
--no-warn-undocumented-member \
./IGUIKit
appledoc-脚本说明.png

生成的文档截图样式

appledoc-ET-01.png

appledoc-ET-10.png

appledoc-ET-11.png

appledoc-ET-12.png

结语

关于注释,两年前自己就做过一次较为全面的了解,算是形成了自己的一套注释风格与规范,现在进一步再总结,过程中借鉴了Apple本身的注释风格,一些开源框架的注释风格,以及一些网上的博客,算是查缺补漏,也希望能够帮助到各位。

注释的写法那么多,最关键的目的还是要写,为了更好的阅读代码。至于你喜欢什么样的注释风格,自己喜欢的风格或者与团队相近即可。

如果有什么建议或问题,欢迎沟通交流。


相关博客or文档:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,440评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,814评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,427评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,710评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,625评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,511评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,162评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,311评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,262评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,278评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,989评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,583评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,664评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,904评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,274评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,856评论 2 339