什么是 静态分析
静态分析,可以帮助我们在代码编写的阶段就能及时发现代码错误,在根上保证工程质量,是iOS开发者最长用到的一种代码调试工具。
Xcode自带有静态分析工具 Analyze,功能有限,无法帮我们在代码编写阶段发现更多的问题。
功能更全、定制化高、效率高的第三方静态检查工具。OClint、Infer、Clang 静态分析器
三个常用的复杂度指标
圈复杂度
是用来衡量一个模块判定结构的复杂程度,数量上表现为独立路径的条数。而独立路径就是在控制流程图中从起点到终点的一条回路。圈复杂度大说明程序代码的判断逻辑复杂。
通常用的计算公式是 V(G) = e - n + 2
, e 代表控制流程图中边的数量(对应代码中顺序结构的部分),n 代表控制流图中结点的数量,包括起点和终点(1、所有终点只计算一次,即使有多个 return 或者 throw; 2、结点对应代码中的分支语句)
一般来说,圈复杂度在以 4 以内是低复杂度,5 到 7 是是中复杂度,8 到 10 是高复杂度,11 以上时复杂度就非常高了,这时需要考虑重构,不然就会因为测试用例的数量过高而难以维护。
NPath 复杂度
NPATH度量会计算遍历一个函数时,所有可能的执行路径的数量。它会考虑嵌套的条件语句,以及由多部分组成的布尔表达式(例如,A && B,C || D,等等)。
解释:在Nejmeh的团队中,每个单独的例程都有一个取值为200的非正式的NPATH限值;超过这个限值的函数可能会进行进一步的分解,或者至少一探究竟。
NCSS 对量
NCSS 度量是指不包含注释的源码行数,方法和类过大会导致代码维护时阅读困难,大的 NCSS 值表示方法或类做的事情太多,应该拆分或重构。一般方法行数不过百,类的行数不过千。
主流的静态分析工具
OCLint
OCLint 是基于 Clang Tooling 开发的静态分析工具,主要用来发现编译器检查不到的那些潜在的关键技术问题。
这些规则已经基本覆盖了具有通用性的规则,主要包括语法上的基础规则、Cocoa 库相关规则、一些约定俗成的规则、各种空语句检查、是否按新语法改写的检查、命名上长变量名短变量名检查、无用的语句变量和参数的检查。除此之外,还包括了和代码量大小是否合理相关的一些规则,比如过大的类、类里方法是否太多、参数是否过多、Block 嵌套是否太深、圈复杂度的检查等。
brew tap oclint/formulae
brew install oclint
xcode 脚本
还需要安装
source ~/.bash_profile
unset LLVM_TARGET_TRIPLE_SUFFIX
xcodebuild -scheme <project_name> -workspace <project_name>.xcworkspace clean
xcodebuild -scheme <project_name> -workspace <project_name>.xcworkspace COMPILER_INDEX_STORE_ENABLE=NO | xcpretty -r json-compilation-database --output compile_commands.json
maxPriority=15000
oclint-json-compilation-database -exclude Pods -exclude build -- -report-type xcode -max-priority-1=$maxPriority -max-priority-2=$maxPriority -max-priority-3=$maxPriority
Clang 静态分析器
Clang 静态分析器是一个用 C++ 开发的,用来分析 C、C++、OC 的开源工具,是 Clang 项目的一部分,构建在 Clang 和 LLVM 之上。Clang 静态分析器的分析引擎用的就是 Clang 库。
下载地址 然后解压就可以了,不需要放到特定目录下。而卸载它的话,删除这个解压后的目录即可。
在 Clang 静态分析器中,常用的就是 scan-build 和 scan-view 这两个工具。
scan-build 是用来运行分析器的命令行工具;scan-view 包含了 scan-build 工具,会在 scan-build 执行完后将结果可视化
scan-build 的原理是,将编译器构建改成另一个“假的”编译器来构建,这个“假的”编译器会执行 Clang 来编译,然后执行静态分析器分析你的代码。
Clang 静态分析器是由分析引擎 (analyzer core) 和 checkers 组成的。所有的 checker 都是基于底层分析引擎之上的。
Infer
Infer 是Facebook 开源的、使用 OCaml 语言编写的静态分析工具,可以对C、Java、OC代码进行静态分析,可以检查出空指针访问、资源泄露以及内存泄露。
brew install infer
//使用
infer -- clang -c Hello.m
source ~/.bash_profile
unset LLVM_TARGET_TRIPLE_SUFFIX
export LC_CTYPE=en_US.UTF-8
xcodebuild -scheme <project_name> -workspace <project_name>.xcworkspace clean
xcodebuild -scheme <project_name> -workspace <project_name>.xcworkspace COMPILER_INDEX_STORE_ENABLE=NO | xcpretty -r json-compilation-database --output compile_commands.json
maxPriority=15000
oclint-json-compilation-database -exclude Pods -exclude build -- -report-type xcode -max-priority-1=$maxPriority -max-priority-2=$maxPriority -max-priority-3=$maxPriority
//https://gist.github.com/ryuichis/755e6297aec13c900cdf 后面的回复
// -exclude Pods 过滤cocoapods 管理的库信息
Clang 静态分析器
Clang 静态分析器是一个用 C++ 开发的,用来分析 C、C++、OC 的开源工具,是 Clang 项目的一部分,构建在 Clang 和 LLVM 之上。Clang 静态分析器的分析引擎用的就是 Clang 库。
下载地址 然后解压就可以了,不需要放到特定目录下。而卸载它的话,删除这个解压后的目录即可。
在 Clang 静态分析器中,常用的就是 scan-build 和 scan-view 这两个工具。
scan-build 是用来运行分析器的命令行工具;scan-view 包含了 scan-build 工具,会在 scan-build 执行完后将结果可视化
scan-build 的原理是,将编译器构建改成另一个“假的”编译器来构建,这个“假的”编译器会执行 Clang 来编译,然后执行静态分析器分析你的代码。
Clang 静态分析器是由分析引擎 (analyzer core) 和 checkers 组成的。所有的 checker 都是基于底层分析引擎之上的。
Infer
Infer 是Facebook 开源的、使用 OCaml 语言编写的静态分析工具,可以对C、Java、OC代码进行静态分析,可以检查出空指针访问、资源泄露以及内存泄露。
brew install infer
//使用
infer -- clang -c Hello.m
Infer 的工作流程:
- 第一个阶段是转化阶段,将源代码转成 Infer 内部的中间语言
- 第二个阶段是分析阶段,分析 infer-out 目录下的文件。分析每个方法,如果出现错误的话会继续分析下一个方法,不会被中断,但是会记录下出错的位置,最后将所有出错的地方进行汇总输出。默认情况下,每次运行 infer 命令都会删除之前的infer-out 文件夹。你可以通过 --incremental 参数使用增量模式。增量模式下,运行infer 命令不会删除 infer-out 文件夹,但是会利用这个文件夹进行 diff,减少分析量。 一般进行全新一轮分析时直接使用默认的非增量模式,而对于只想分析修改部分情况时,就使用增量模式。
对于这三款工具,都是基于 Clang 库开发的。
Clang 静态分析器和 Xcode 的集成度高,也支持命令行。不过,它们检查的规则少,基本都是只能检查出较大的问题,比如类型转换问题,而对内存泄露问题检查的侧重点则在于可用性。
OCLint 检查规则多、定制性强,能够发现很多潜在问题。但缺点也是检测规则太多,反而容易找不到重点;可定制度过高,导致易用性变差。
Infer 的效率高,支持增量分析,可小范围分析。可定制性不算最强,算中等。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论