Cocoa 代码注释与文档生成

本文的文档规范部分的内容参考自:NSHipster 的 Swift Documentation 作者 & Nate Cook

本文知识目录

背景

曾经以为好的代码是可以自我解释不需要注释的,后来发现不是这样的。就算是个人项目,代码注释的重要性也是毋庸置疑。毕竟人的记忆只有七秒!

一个开发者是从其他语言转到 Cocoa 开发,大都会被它冗长的代码所 到,Objective-C 的冗长使得其代码就是有效的自我说明。有如 stringByAppendingPathExtension: 以及参数的显式类型,这样的方法一般不会给人留下太多的想象空间。不过 Swift 就有所不同了。

但即使是自我说明的代码也可以通过说明文档加以改进,而且只需少量的努力就可以给别人产生显著的好处。

文档生成工具

每一个现代编程语言都有注释:由一个特殊的字符序列标记的非可执行的自然语言,如 ///**/--。使用特殊格式注释的文档,提供了代码的辅助解释和上下文,可以用编译工具提取和解析。

从 00 年代早期,Headerdoc 就一直作为苹果首选的文档标准。从 Perl 脚本解析勉强的 Javadoc 注释作为出发点,Headerdoc 最终成为了苹果在线文档及 Xcode 中的开发者文档的后台引擎。

随着 WWDC 2014 的发布,开发者文档被翻修并重新设计,包含了 Swift 和 Objective-C 的支持。

appledoc

类似 Javadoc, appledoc 能够从 .h 文件生成 HTML 和 Xcode 兼容的 .docset 文档。

Doxygen

主要用于 C++,但一般在 iOS / OS X 的开发者社区不很受待见。

Jazzy

支持 Objective-C 和 Swift,通过对 Clang 和 SourceKit 的 hook 方式获取代码 AST 树来精准获取注释。

Cocoa 文档规范

就像许多苹果开发者生态系统一样,Swift 改变了一切。 本着 “与时俱进,与新共存” 的精神,Xcode 7 将Headerdoc 换成了粉丝最喜欢的 Markdown,尤其是 Swift 风格的 Markdown。

Xcode 中生成 document 模版的快捷键为 option(alt) + cmd + /

下面为最基本的 Cocoa 注释。

Objective-C 风格的注释:

/// Let's say something
///
/// @param bar I'm paramter
/// @return I'm return value
- (id)fooBar:(NSString *)bar;

Swift 风格的代码注释:

///
/// Let's say something
///
/// - Parameter bar: I'm paramter
/// - Returns: I'm return value
func foo(bar: String) -> AnyObject { ... }

基本标记规则

文档注释通过使用 /** ... */ 的多行注释或 ///... 的单行注释来进行区分。在注释块里面的内容支持标准的 Markdown 语法,规则如下:

  • 段落由空行分隔
  • 无序列表可由多个项目符号字符组成:-+*
  • 有序列表使用阿拉伯数字 1,2,3,… 后跟一个点符 1. 或右括号 1) 或两侧括号括起来 (1)
  • 标题使用 # 作为前缀,内容的分割线使用 ---
  • 支持 链接图片,会将基于Web的图像下载并直接在 Xcode 中显示
/**Hello, documentation[土土Edmond木](https://looseyi.github.io/)# ListsYou can apply *italic*, **bold**, or `code` inline styles.---# Unordered Lists- Lists are great,- but perhaps don't nest;- Sub-list formatting...- ...isn't the best.---## Ordered Lists1. Ordered lists, too,2. for things that are sorted;3. Arabic numerals4. are the only kind supported.*/

预览效果

摘要和说明

文档注释的开头部分将成为 “摘要“ Summary,余下的其他内容将一起归入 “讨论” Discussion

如果文档注释以段落以外的任何内容开头,则其所有内容都将放入讨论中。

参数和返回值

Xcode可以识别一些特殊字段,并使它们与符号描述分开。 当将 ParameterReturnThrows 置为项目符号项后带上冒号 : 时,它们会在快捷提示和帮助文档中与 讨论 分段。

  • Parameters: 行首以 - Parameter <param name>: 开始并带上参数的描述
  • Return values: 行首以 Returns: 开始并带上返回值的描述
  • Thrown errors: 行首以 Throws: 并配上可能抛出的异常描述,由于 Swift 不会对超出错误一致性的抛出错误进行类型检查,因此正确记录错误尤为重要。

本文我们基本以 Swift 代码作为示例。如果代码是 Objective-C,格式稍微有一些区别。

以返回值的关键字为例。在 Swift 中,我们编写 - return:,但在 Objective-C 中,您将编写 @return。 有关更多详细信息,请参见 Apple 的 HeaderDoc 用户指南

/**Creates a personalized greeting for a recipient.- Parameter recipient: The person being greeted.- Throws: `MyError.invalidRecipient`if `recipient` is "Derek"(he knows what he did).- Returns: A new string saying hello to `recipient`.*/
func greeting(to recipient: String) throws -> String {guard recipient != "Derek" else {throw MyError.invalidRecipient}return "Greetings, (recipient)!"
}

如果你的方法有多个参数的话,可以通过 Parameters: 字段加上无序列表符来注释:

/// Returns the magnitude of a vector in three dimensions
/// from the given components.
///
/// - Parameters:
///     - x: The *x* component of the vector.
///     - y: The *y* component of the vector.
///     - z: The *z* component of the vector.
func magnitude3D(x: Double, y: Double, z: Double) -> Double {return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2))
}

其他字段

除了上面的常用字段,Swift 风格的 Markdown 还定义了其他几个字段:

类型Algorithm/Safety InformationPrecondition Postcondition Requires Invariant Complexity Important WarningMetadataAuthor Authors Copyright Date SeeAlso Since VersionGeneral Notes & ExhortationsAttention Bug Experiment Note Remark ToDo

可以按以下方式松散地组织它们,每个字段在快速帮助中均显示为粗体标题,后跟一段文本:

- 字段名:
字段描述的内容从下一行开始

代码块

文档注释也支持嵌入 Code 来演示功能的正确用法或实现细节。插入代码可以通过添加三个反引号 (```) :

/**The area of the `Shape` instance.Computation depends on the shape of the instance.For a triangle, `area` is equivalent to:```let height = triangle.calculateHeight() let area = triangle.base * height / 2```
*/
var area: CGFloat { get }

或者三个反波浪号 (~~~):

/**The perimeter of the `Shape` instance.Computation depends on the shape of the instance, and isequivalent to:~~~// Circles:let perimeter = circle.radius * 2 * Float.pi// Other shapes:let perimeter = shape.sides.map { $0.length }.reduce(0, +)~~~*/
var perimeter: CGFloat { get }

MARK / TODO / FIXME

在 Objective-C 中,我们通过预处理器指令 #pragma mark 将功能划分为有意义的,易于导航的部分。 在 Swift中,可以通过注释 // MARK: 实现相同的功能。以及我们常用的其他 tag:

  • // MARK:
  • // TODO:
  • // FIXME:
  • // NOTE:

为了展示这些新标签的实际作用,下面介绍了如何扩展 Bicycle 类以采用 CustomStringConvertible 协议并实现 description属性。

// MARK: - CustomStringConvertibleextension Bicycle: CustomStringConvertible {public var description: String {var descriptors: [String] = []...// FIXME: Use a distance formatterdescriptors.append("...")// TODO: Allow bikes to be named?return descriptors.joined(separator: ", ")}
}

给一个类添加完整的注释

///   A two-wheeled, human-powered mode of transportation.
class Bicycle {/// Frame and construction style.enum Style {/// A style for streets or trails.case road/// A style for long journeys.case touring/// A style for casual trips around town.case cruiser/// A style for general-purpose transportation.case hybrid}/// The style of the bicycle.let style: Style/// The size of the frame, in centimeters.let frameSize: Int/// The number of trips traveled by the bicycle.private(set) var numberOfTrips: Int/// The total distance traveled by the bicycle, in meters.private(set) var distanceTraveled: Double/**Take a bike out for a spin.Calling this method increments the `numberOfTrips`and increases `distanceTraveled` by the value of `meters`.- Parameter meters: The distance to travel in meters.- Precondition: `meters` must be greater than 0.*/func travel(distance meters: Double) {precondition(meters > 0)distanceTraveled += metersnumberOfTrips += 1}
}

完整的 ‍♀️ 文档,戳这里

Library 项目文档的生成

接下来我们一起来实践一下,如何使用 Jazzy 来生成项目的 API 文档。

首先,Jazzy 支持对 Swift 和 Objective-C 的 Xcode project 项目生成文档,对于 SwiftPM 也是近期刚支持的。我们会逐步进阶,从一个独立的 Swift 和 ObjC 项目,再到混编项目,最后是基于 CocoaPods 来生成私有库文档。

为 Swift 项目生成文档

Jazzy 默认是解析 Swift 代码注释来生成文档。我们先尝试为 Alamofire 生成 HTML 文档。

首先需要安装 Jazzy,Jazzy 是一个 Gem 依赖库,更多了解 Gem 请看

版本管理工具及 Ruby 工具链环境​juejin.im

[sudo] gem install jazzy

不过由于 Alamofire 在项目的 Gemfile 中已经添加了 Jazzy 的依赖,所以我们这里使用 bundle install 来安装。最后通过 -o Docs 将文档输出到项目的根目录,完整命令如下:

$ git clone https://github.com/Alamofire/Alamofire
$ cd Alamofire
$ bundle install
$ bundle exec jazzy -o Docs

生成文档的效果:

Jazzy 默认会读取项目中的 README.mdREADME.markdownREADME.mdownREADME 文档内容作为 index page 的内容。

对于 Swift module 项目,Jazzy 在生成文档时会自动寻找项目根目录下的 project,然后执行 xcodebuildswift build 来生成 Clang AST,再通过 SourceKit 来生成注释文档。

对于支持 SwiftPM 的项目,我们也可以通过指定 --wift-build-tool 来生成文档:

$ bundle exec jazzy -o Docs --module Alamofire --swift-build-tool spm --build-tool-arguments -Xswiftc,-swift-version,-Xswiftc,5

为 Objective-C 项目生成文档

Objective-C 项目文档的生成需要多几个参数,这里我们以 AFNetworking 为例。

clone 代码到本地后需要修改 AFNetworking 目录下的 Gemfile 添加 Jazzy 依赖:

source "https://rubygems.org"gem "fastlane"
gem "cocoapods"
gem "jazzy"
gem "xcode-install"

接着安装 jazzy 生成 docs 文档:

$ bundle install
$ bundle exec jazzy -o Docs --objc --umbrella-header AFNetworking/AFNetworking.h --framework-root AFNetworking

  • --objc:指定为 Objective-C 生成文档
  • --umbrella-header:指定 Objective-C framework 的 Umbrella header 路径
  • --framework-root: 指定 Objective-C framework 路径

为 Swift & Objective-C 混编项目生成文档

Jazzy 对于混编项目的支持目前还不是很友好。想要生成混编代码注释的文档,我们需要事先生成 json 格式的中间产物,再传递给 Jazzy 来生成完整的文档。这里需要用到工具 sourcekitten

先看基于混编项目生成文档的方式:

# 输出 SourceKitter 的 Swift 文档数据到 json
sourcekitten doc -- -workspace MyProject.xcworkspace -scheme MyScheme > swiftDoc.json# 输出 SourceKitter 的 Objective-C 文档数据到 json
sourcekitten doc --objc $(pwd)/MyProject/MyProject.h -- -x objective-c  -isysroot $(xcrun --show-sdk-path --sdk iphonesimulator) -I $(pwd) -fmodules > objcDoc.json# 合并 swift 和 Objective-C json 并输出文档
jazzy --sourcekitten-sourcefile swiftDoc.json,objcDoc.json

当然 Jazzy 还有其他很多使用参数这里就不一一介绍了,大家感兴趣的可以查看官方文档或者使用 jazzy --help <command>

总结

  • 本文介绍了如何按照 Apple 的标准写出 Swift 风格的代码注释,以及基于 Jazzy 来生成简单的 HTML 文档。
  • 也许大家平时不太注意文档的规范和书写,但是当我们需要查看系统 framework 或者是开源的 API 时总觉得注释里的说明不够详尽,所以从现在开始写好文档吧。
  • 好文档不仅可以可以记录代码的实现思路和原理,同时也能够更好的将核心思想传递给接手的人,更好的维护。
  • 基本上优秀的开源库都要非常详尽的说明文档,比例 Alamofire,QMUI 都很值得学习。

知识点问题梳理

这里罗列了四个问题用来考察你是否已经掌握了这篇文章,如果没有建议你加入**收藏 **再次阅读:

  1. Objective-C 和 Swift 代码注释的区别?
  2. 对包含多个参数的方法注释与单个参数对方法有什么区别?
  3. 代码注释都支持哪些 Markdown 格式?
  4. Jazzy 支持几种模式的文档生成?

javadoc文档的生成方法_Cocoa 代码注释与文档生成相关推荐

  1. 生成酷炫代码注释(根据图片生成)

    实现详见我的博客

  2. Doxygen——根据代码注释生成文档的工具

    文章目录 1 简介 2 安装 3 使用 3.1 注释代码 3.2 使用doxywizard生成文档 4 用例 4.1 OpenCV 4.2 Apollo 5 参考 1 简介 Doxygen是一个可以根 ...

  3. IDEA自动生成方法和文件注释(实用)

    IDEA自动生成方法和文件注释(实用) 1.定义Java文件注释 打开idea,按照以下步骤打开 File => setting => editor => File and Code ...

  4. C# 代码注释规范文档

    C# 提供一种机制,使程序员可以使用含有 XML 文本的特殊注释语法为他们的代码编写文档.在源代码文件中,具有某种格式的注释可用于指导某个工具根据这些注释和它们后面的源代码元素生成 XML.使用这类语 ...

  5. js代码注释生成文档工具-jsdoc

    需求 将js和ts的代码注释生成api文档 思路 先将ts转成js,再统一处理js文件,用jsdoc工具来生成html文件. JsDoc 是js文档生成工具,它从javascript程序源代码中抽取类 ...

  6. cosmos官方nameservice测试项目详解(代码注释+官方文档错误纠正)

    目录 文章目录 目录 介绍 1.Getting Started 2.Application Goals State Messages 3.Start your application 4.Types ...

  7. RabbitMQ官方文档知识点总结合集+代码注释(中文+Java版)

    全文代码.MD格式文档的github连接(求star~):https://github.com/Ruoyi-Chen/RabbitMQ-demos 文章目录 全文代码.MD格式文档的github连接( ...

  8. 代码注释生成文档之Doxygen 附说明+下载连接

    上个星期闫海静老师给我们讲如何使用PEAR把特定的批注转换成为说明文件,在闫海静老师给我们演示完安装和使用以后,我亲自操作了一下,感觉这东西对于我来说有点不适应,在安装过程中还需重启这让人有点无法接受 ...

  9. 【Python黑科技】图片太大不能上传?三种压缩图片大小的方法(代码注释详细)

    目录 实现效果 原图大小8.46MB PIL库quality降低图片质量方式压缩图片366KB PIL库thumbnail压缩图片大小来压缩图片985KB OpenCV缩放图片大小来压缩图片 177K ...

最新文章

  1. CentOS6.8 编译安装LNMP
  2. MyBatis入门示例
  3. 猛男把400+条猫咪叫声做成数据集,可识别猫咪的3种不同状态丨开源
  4. 参加51CTO培训,PMP考试通过啦
  5. 【开发环境】Android 命令行中执行 Java 程序 ( IntelliJ IDEA 中创建 Java / Kotlin 工程 | dx 打包 DEX 字节码文件 | dalvikvm 命令 )
  6. MySQL 数据库规范--调优篇(终结篇)
  7. iis7.5 php伪静态,Windows Server 2008 下WordPress IIS7.5伪静态规则设置(最新)
  8. CSS 文本缩进text-indent属性
  9. linux双系统uefi引导修复,Windows和Ubuntu双系统,修复UEFI引导的两种办法
  10. Python自动化办公 | 补写178份Word日报!
  11. 瓜子二手车:急招IoT架构师,相当阿里P9
  12. 如何从零开始系统运营微信公众号?
  13. Unity Audio Mixer介绍
  14. 修改迅雷下载中“边下边播”的默认播放器
  15. protues仿真51单片机教程
  16. [笔记] APIO 2018 Day1
  17. Windows server 2012 R2系统怎么安装IIS管理器?
  18. 详解SMS2003部署Windows 2003
  19. 【笔记】莫比乌斯反演(1)
  20. 矩阵中的主元是什么意思(在消去过程中起主导作用的元素)

热门文章

  1. Spring boot与Quartz实现任务定时提醒
  2. 阿里云 Debian 9.2 安装 Java Web 环境
  3. CentOs6.6安装Python3
  4. cocos2d-js 网络请求之GET/POST
  5. 昨天晚上学MFC的ADO,跟着书上的讲解和例子,完成了ADO的初级使用。
  6. 框架中要懂的一些术语
  7. 大数据之-Hadoop3.x_MapReduce_ReduceTask源码解析---大数据之hadoop3.x工作笔记0127
  8. AndroidStudio_报错PluginApplicationException: Failed to apply plugin [id ‘com.and---Android原生开发工作笔记227
  9. 大数据之-Hadoop完全分布式_集群时间同步---大数据之hadoop工作笔记0043
  10. Error: EBUSY: resource busy or locked, lstat ‘D:\DumpStack.log.---基于Vue的uniapp手机端_前端UI_uview工作笔记004