如何在 Objective-C 中检测未使用的方法和#import

Posted

技术标签:

【中文标题】如何在 Objective-C 中检测未使用的方法和#import【英文标题】:How to detect unused methods and #import in Objective-C 【发布时间】:2010-11-30 05:28:54 【问题描述】:

在一个 iPhone 应用程序上工作了很长时间后,我意识到我的代码很脏,包含几个#import 和根本没有调用或没有用的方法。

我想知道是否有任何编译器指令或方法来检测那些无用的代码行。 Xcode 是否有任何工具可以检测到这一点?

【问题讨论】:

【参考方案1】:

您可以使用 Xcode Analyzer 来查找该问题和其他问题。

http://help.apple.com/xcode/mac/8.0/#/devb7babe820

您还可以转到项目和目标构建并在构建设置下添加更改警告首选项。请参阅本指南:

http://oleb.net/blog/2013/04/compiler-warnings-for-objective-c-developers/

【讨论】:

我希望分析器报告未使用的导入,但它似乎没有。【参考方案2】:

正如 paddydub 所说,AppCode 做得很好。我试过了,只用了 10 分钟:

转到Code > Optimize Imports...,或^ + ⌥ + O

这是一个描述如何做到这一点的视频:Detection of unused import and methods in AppCode

【讨论】:

【参考方案3】:

Appcode 具有代码检查功能,可以发现未使用的导入和代码。

【讨论】:

那么,你的意思是我们应该只为这个功能安装 Appcode?​​span> 如果它对你有用,是的!【参考方案4】:

我们一直在使用一些本地开发的 Ruby 代码,现在提取到一个名为 fui 的 gem 中:https://github.com/dblock/fui

【讨论】:

【参考方案5】:

我最近编写了一个脚本来查找未使用的(或重复的)#import 语句:https://gist.github.com/Orangenhain/7691314

脚本获取一个 ObjC .m 文件并开始依次注释掉每个 #import 行,并查看项目是否仍然可以编译。您将不得不更改 BUILD_DIR 和 BUILD_CMD。

如果您使用 find 命令让脚本在多个文件上运行,请确保使用实际使用所有这些文件的 BUILD_CMD(否则您会看到一个包含大量未使用的导入语句)。

我在不知道 AppCode 具有类似功能的情况下编写了此代码,但是当我测试 AppCode 时,它​​并没有此脚本那么彻底(但[对于整个项目] 更快)。

【讨论】:

它只适用于重复,未使用的导入不会被删除。【参考方案6】:

最近,我将一个大型项目从 Carbon 更改为 Cocoa。在此结束时,有相当多的孤立文件不再使用。我写了一个脚本来找到他们基本上是这样做的:

确保源代码全部签入到颠覆(即干净) 确保当前构建没有错误(即 xcodebuild 返回 0 状态) 然后,对于目录中的每个源文件,清空(即删除内容,截断长度)源和头文件,尝试构建,如果失败,则恢复文件,否则,将它们留空。

运行此程序后,还原并删除所有清空的文件,编译然后删除所有错误的#imports。

我还要补充一点,你需要避免从 .xib 或 .sdef 文件中引用的文件,并且可能还有其他动态链接的情况,但它仍然可以让你很好地了解可以删除的内容。

可以使用相同的技术来查看可以删除哪些#imports - 不是截断文件,而是依次删除文件中的每个#import,然后查看构建是否失败。

【讨论】:

【参考方案7】:

Xcode 允许您(取消)检查特定编译器警告的设置,这些警告可以警告您某些类型的未使用代码。 (在源列表中选择项目,然后选择 File > Get Info,然后选择 Build 选项卡。)这里有一些(对我来说显示为 Clang 和 GCC 4.2)可能感兴趣:

未使用的函数 未使用的参数 未使用的值

我没有看到任何用于检测未使用的导入的选项,但这有点简单——低技术方法只是注释掉导入语句,直到出现编译错误/警告。

未使用的 Objective-C 方法比未使用的 C 函数更难检测,因为消息是动态分派的。警告或错误可以告诉您存在潜在问题,但缺少警告或错误并不能保证您不会出现运行时错误。


编辑:检测(可能)未使用的方法的另一个好方法是检查实际执行的代码覆盖率。这通常与自动化单元测试一起完成,但并非必须如此。

This blog post 是对使用 Xcode 进行单元测试和代码覆盖率的不错介绍。 gcov 部分(顺便说一下,它只适用于 GCC 生成的代码)解释了如何让 Xcode 构建可以记录执行频率的检测代码。如果您在模拟器中测试应用程序的构建,然后在其上运行 gcov,您可以查看使用 CoverStory(相当简单的 GUI)或 lcov(Perl 脚本)之类的工具执行了哪些代码创建 html 报告)。

我将gcovlcov 用于CHDataStructures.framework,并在每次SVN 提交后自动生成coverage reports。同样,请记住,将执行覆盖率视为对哪些代码“死”的明确衡量标准是不明智的,但它肯定有助于确定可以进一步调查的方法。

最后,由于您正在尝试删除死代码,我认为您会发现这个 SO 问题也很有趣:

Profiling Objective-C binary image size

【讨论】:

我不确定你的意思是什么...静态分析器可以发现很多问题,但是如果你将消息发送到类型为 id的变量>,或者创建一个选择器在运行时调用,静态分析器不能保证代码真的没有被使用。如果仍然需要的代码被删除,那你就会得到运行时错误。我错过了什么吗? 此外,在运行时基于字符串创建的选择器非常普遍。 当然,在某些情况下,您的动态代码可能会通过更强烈的类型转换(即返回某些内容而不是 id)得到更好的服务。运行时类型是 Cocoa/Objective-C 编程的一个强项,但有时更多地考虑强类型会更好地维护维护和可读性。 哦,我绝对同意。我的经验法则是静态类型(就像我在 Java 中那样),除非我真的需要动态类型,这很少见,但偶尔会发生。然而,仅仅与 Cocoa 类交互(例如,指定一个委托)可能会导致难以追踪的动态和执行路径。哎呀,任何具有运行循环和多个线程的程序都可以是不平凡的......

以上是关于如何在 Objective-C 中检测未使用的方法和#import的主要内容,如果未能解决你的问题,请参考以下文章

使用 Objective-C 在实时视频中检测眼睛?

Objective-C 峰值检测加速框架

Objective-c:如何检测视图上的双击?

如何在 Objective-C 中不旋转的视图控制器中检测设备的真实方向?

intersectsNode 未检测到交叉点

如何检测按下的按钮并将其显示在另一个视图上? Objective-C