XcodeHeaderDoc教程
文章目录
【注意】最后更新于 August 28, 2014,文中内容可能已过时,请谨慎使用。
HeaderDoc 是在Xcode 5 和 iOS7 发布时,新增的一个命令行工具,功能:可以从代码中自动生成格式良好的HTML文档——当然,必须依赖于特定格式的注释来完成的。
另外,Xcode 还会在 quick look 面板中以HeaderDoc风格显示你的注释。
通过本教程,将学习如下几点:
- 如何书写 HeaderDoc 风格的注释
- 分如何在 Xcode 中预览文档
- 如何生成 HTML 文档
- 如何使用 VVDocumenter-Xcode(一个易于使用的第3方文档制作工具)
准备工作
下载本教程中用到的 示例项目
这个简单的示例程序只包含了两个类:
- Car: 包含几个属性及一个 “drive” 方法以及一个 completion 块。
- MathAPI: 包含了1个方法,用于累加两个数。 现在,这两个类还没有任何注释。以便演示如何通过 HeaderDoc 为这两个类创建文档。
HeaderDoc 注释
HeaderDoc 可以从命令行中运行,也可以通过 Xcode 运行。它扫描文件中以某种格式书写的注释,包括这3种形式: 这3中语法在 Xcode 中产生同样效果的文档
注释 1. 一般用于单行注释
/// Your documentation comment will go here
注释 2.
/** * Your documentation comment will go here */
注释 3: 一般用于较长的注释块
/*! * Your documentation comment will go here */
注意:在注释2和注释3中,在每一行开头都会有一个额外的*,直至结尾的 */。这仅仅是为了美观,而不是必须的。
HeaderDoc 标签
当 HeaderDoc 发现上述3种注释,它就开始寻找其中的HeaderDoc 标签。HeaderDoc 标签 用来修饰HeaderDoc 注释。
HeaderDoc 标签以 @ 符号开头,然后是关键字,然后是一个空格,最后才是相应的文本(例如 @param foo)。 HeaderDoc 标签可以分为两种:
顶级标签: 这些标签声明所要注释的对象的类型(例如头部声明、类、方法等等)。
- 顶级标签,例如 @typedef,用于表示 typedef 定义的类型,比如枚举、结构体和函数指针。
- HeaderDoc 能够根据上下文自动产生顶级标签,因此通常不是必须的。
二级标签:这些标签才是具体的注释内容。
- @brief: 简单描述你准备文档化的数据的类型,方法等等。
- @abstract: 等于 @brief。
- @discussion: 类似 @abstract 和 @brief,但允许多行。它不是必须的,仅仅是为了使描述更清晰。
- @param: 描述方法、回调或函数的参数名称。
- @return: 描述方法或函数的返回值。(等同于 @result)
具体实现
属性的文档化
用 Xcode 打开DocumentationExamples 项目, 打开ViewController.h, 在** car **属性的前面,加入一行注释:
/*! * @brief The ViewController class' car object. */
@property (nonatomic) Car *car;
编译项目。编译结束,按住 alt/option 键,点击car 变量名。你将看到pop菜单中显示了刚才的注释内容。 另一种方法:切换到Utitlities 面板的Quick Help 检查器窗口。点击 car 变量名,通过Quick Help,你将看到如下效果:
方法的文档化
MathAPI包含一个方法需要文档化。打开MathAPI.h,找到addNumber:toNumber:
。
这个方法有两个参数及一个返回值。因此需要一个 @description 标签、两个@param标签,以及一个@return 标签,如下面所示:
/*! * @discussion A really simple way to calculate the sum of two numbers.
* @param firstNumber An NSInteger to be used in the summation of two numbers
* @param secondNumber The second half of the equation.
* @return The sum of the two numbers passed in.
*/
+ (NSInteger)addNumber:(NSInteger)firstNumber toNumber:(NSInteger)secondNumber;
编译,再 alt + 左键:
问题: 在 Xcode 文本编辑窗口,很多地方都支持 alt+左键。请确保你点击在正确的地方。在上面的例子里,你应当在addNumber: 和 toNumber: 两处使用 alt+左键。
你也许不知道,这个方法的实现真的很恶心。它只能使用非负数作为参数。为了让用户明白这一点,你应当在注释中添加更多的说明。因此,我们可以在 @return 前面加入一个 @warning 标签。
* @warning Please make note that this method is only good for adding non-negative numbers.
编译项目,然后使用 alt+左键。我们添加的 @warning 标签效果如下:
Code Snippets,让一切变得更简单:
一个snippet 是一个可以重用的代码块(存储在 snippet 库中)。Snippets 甚至可以包含一些需要你去填充的占位符。 这意味着, 可以用 snipppet来进行文档化。
在 MathAPI.h 中,在原有的注释上面加入以下内容:
/*! * @discussion
* @param
* @return
*/
注意,当粘贴上述代码时,“”之间的内容会变成一个token,意味着可以通过 tab 键在 token 之间来回切换。就像编写代码时的自动完成功能。
学习使用Code Snippets工具
打开 Utilities 面板中的 CodeSnippets Library 检查器窗口,选中上述注释块,将它拖到该检查器窗口中(从某个 token 例如开始拖): 将会弹出一个编辑窗口让输入 snippet 的某些信息,并以此来创建一个自动完成快捷方式。要修改某个snippet时,直接点击 Code Snippet Library 中的 snippet,然后点 Edit 按钮。按照如下形式填写:
要想让 snippet 生效,首先删除原有注释,然后将鼠标放到addNumber:toNumber: 方法的 + 号前面,输入doccomment,然后回车,该snippet 将自动生成。然后,通过 Tab 键在3个 token 间移动,并填充它们。最终完成的文档化结果如下:
/*! * @discussion A really simple way to calculate the sum of two numbers.
* @param firstNumber An NSInteger to be used in the summation of two numbers.
* @param secondNumber The second half of the equation.
* @warning Please make note that this method is only good for adding non-negative numbers.
* @return The sum of the two numbers passed in.
*/
@param 标签和 @warning 标签需要手动书写。
Typedefs的文档化
打开 Car.h,在 class 之,有一个NS_ENUM,即 typedef enum,一个块,几个属性,一个空方法等,需要文档化。
还记得 @typedef 标签吗? 这个顶级标签稍微特殊一点。它可以对typedef enum 或者 typedef struct 的类型进行注释。 根据注释的对象的不同,它会包含与定义的类型相关的二级标签。
以 enum 为例,它会包含 @constant 标签,用于每个常量(对于struct,则会是 @field 标签)。
找到 enum OldCarType。它包含两个常量,是用于古典汽车的。在typedef 声明之上,将原来的注释替换为:
/*! * @typedef OldCarType
* @brief A list of older car types.
* @constant OldCarTypeModelT A cool old car.
* @constant OldCarTypeModelA A sophisticated old car.
*/
typedef enum {
/// A cool, old car.
OldCarTypeModelT,
/// A sophisticated older car.
OldCarTypeModelA
} OldCarType;
编译,然后在 OldCarType 或上OldCarTypeModelT使用alt + 左键。
在这个类中只有一个 NS_ENUM,因此接下来进行进行文档化。常量已经注释了,只要对整个NS_ENUM 进行一个总体的注释就可以了。
/*! * @typedefCarType
* @brief Alist of newer car types.
* @constantCarTypeHatchback Hatchbacks are fun, but small.
* @constantCarTypeSedan Sedans should have enough room to put your kids, and your golfclubs
* @constantCarTypeEstate Estate cars should hold your kids, groceries, sport equipment,etc.
* @constantCarTypeSport Sport cars should be fast, fun, and hard on the back.
*/
注意:这个enum 是通过宏来声明的,悲催的 Xcode 不能完全支持和 typedef enum 一样的文档特性,虽然NS_ENUM 实际上是声明 enums 的推荐的方法。
typedef block 文档化
/*! * @brief A block that makes the car drive.
* @param distance The distance is equal to a distance driven when the block is ready to execute. It could be miles, or kilometers, but not both. Just pick one and stick with it. ;]
*/
typedef void(^driveCompletion)(CGFloat distance);
typedef block 的文档化和之前的并无多少不同,它包含了:
- 一个 @brief 标签,简单说明了一下这个块的作用。
- 一个 @param 标签,说明调用块时需要传递的参数。
添加格式化代码到文档中
例如,Car 类的 driveCarWithComplete: 方法。
这个方法以块作为参数,因为块对于新手来说一般比较困难,因此最好是告诉程序员如何使用这个方法。
这需要使用 @code 标签。在 driveCarWithCompletion方法声明之前添加如下内容:
/*! * @brief The car will drive, and then execute the drive block
* @param completion A driveCompletion block
* @code [car driveCarWithCompletion:^(CGFloat distance){
NSLog(@"Distance driven %f", distance);
}];
*/
编译,在方法名上使用alt+左键。如下图所示:
检查文档
学会了如何添加注释,如果 Xcode 能帮你检查你的工作,就像Xcode会自动检查代码中的语法错误,那岂不是更好?有一个好消息,Clang 有一个标志,叫做“CLANG_WARN_DOCUMENTATION_COMMENTS”,可以用于检查 HeaderDoc 格式的注释。
打开 DocumentationExamples的项目设置,点击 Build Settings,找到 DocumentationComments, 将值设置为 YES。 如下,打开 MathAPI.h,将第一个 @param 标签的参数名由firstNumber 修改为 thirdNumber,然后编译。 有一个警告发生,甚至提出了修改建议。它不会影响任何事情,但有助于检查文档中的错误。
特殊注释
Xcode 还支持几种特殊注释,对于你或者使用你代码的人非常有用。
打开 Car.m,在 driveCarWithCompletion: 方法中,在调用completion 块之前添加下列注释:
// FIXME: This is broken
// !!!: Holy cow, it should be checked!
// ???: Perhaps check if the block is not nil first?
这里出现了3中注释:
- FIXME: 某个地方需要修正
- !!!: 某个地方需要注意。
- ???: 代码中有问题,或者代码是可疑的。
这些注释不但有助于浏览代码,而且 Xcode 绘制 Jump Bar 中显示它们。点击Jump Bar,如下图所示:
你将看到这3个注释以粗体显示:
到此,你已经完全掌握了如何对项目进行文档化。花一些时间对项目的其他属性和方法操作一番,并加入一些自己的东西。看看在注释块中改变一些东西或者删除某个标签会发生什么。这将让你明白注释格式如何对文档造成影响的。
#用headerdoc2html 创建 HTML文档 文档化是由一个 HeaderDoc 工具完成的。当 Xcode 安装时,它就已经安装好了。 它除了解释已添加的注释,显示一个弹出菜单以及将注释在Quick Help 中显示之外,还可以在文档化之后创建 HTML、XML 以及联机帮助手册。
本节介绍 HTML 文件的制作。如果你对用 HeaderDoc 如何创建在线文档感兴趣,请参考HeaderDoc 用户指南.
打开终端,转到 DocumentationExamples 项目目录:
cd /path/to/your/folder
确保该路径下包含了 Xcodeproject 文件(“DocumentationExamples.xcodeproj”)。
然后用下列命令创建 HTML 文档:
headerdoc2html -o ~/Desktop/documentation DocumentationExamples/
此时终端会有许多输出。当创建完毕,返回桌面,出现一个名为documentation 的目录。双击打开,找到 Car_h 目录,打开 index.html:
headerdoc2html 脚本有两个参数:
So what justhappened? Well, you ran the headerdoc2htmlscript with 2 options:
- -o ~/Desktop/documentation – 这个参数指定输出的 Html 文件路径——即桌面的 documentation 目录。
- DocumentationExamples/ – 该参数指定要解析的源文件位于 DocumentationExamples 目录(不包含项目目录下的其他目录,因为它们并不包含源代码)
问题:
- 最新版本headerdoc2html有个问题,用 google chrome打开 index.html后,左边的目录显示不正常,但 Safari打开正常。
- 最新版本的headerdoc2html 不能正确解析 /// 类的注释,可以使用 /*! 类型的注释代替。
这很酷,但还可以更进一步。除了手动进入到输出目录中进行导航,HeaderDoc还会创建一个主目录索引。 返回终端,导航至新建的 documentation 目录,输入:
cd ~/Desktop/documentation
然后输入命令,创建内容索引:
gatherheaderdoc .
gatherheaderdoc自动查找目录,为 . 目录(表示当前目录)创建索引。 用 Finder 打开 documentation 目录。你会发现多出一个 masterTOC.html 文件。打开它,它将列出所有已文档化的属性、方法、枚举和块的链接。 你可以将所有 HTML 文件放到 web 服务器上,然后所有人都可以访问你的文档!
#VVDocumenter-Xcode
最后的内容是 VVDocumenter-Xcode,一个第三方 Xcode插件,它能让你的文档化工作简单至比使用早先介绍的 Code Snippet 更容易。
首先,从 Github 下载插件。
你所需要做的全部工作就是打开项目,然后 Build。它会将插件自动安装到~/Library/ApplicationSupport/Developer/Shared/Xcode/Plug-ins 目录。
然后重启 Xcode。再次打开 DocumentationExamples项目。在 MathAPI.h,删除 addNumber:toNumber
方法的注释块,然后在方法声明上面输入:
///
VVDocumenter-Xcode 将自动创建注释块,包括所有必要的 @param 标签以及自动完成 token。
打开 Car.h,删除 NS_ENUM CarType 的注释,以及每个常量的注释。在NS_ENUM 声明之上,输入:
///
这回,它会在 enum 之上创建 discussion 标签,甚至还每个常量上面放入了必要的注释!
VVDocumenter-Xcode 使你的生活更加轻松。如果你想定制VVDocumenter-Xcode,在Xcode中,使用 Window>VVDocumenter菜单。
这里,你可以改变自动完成关键字、注释风格以及其他。你想怎样定制 VVDocumenter-Xcode都行。VVDocumenter-Xcode 为我省下了大量的时间! 接下来做什么?
最终完成的示例项目在 这里下载。
在你自己的代码中进行文档化。尝试自己编写 code snippet 并使用VVDocumentor。
文章作者 iTBoyer
上次更新 2014-08-28