编译时检查 Xcode 中的有效文件引用

问题描述 投票:0回答:4

是否可以强制 Xcode 编译器验证代码中引用的文件是否有效?

当您自然地通过 NSString 以编程方式引用文件时,Cocoa 开发中有多个要点:

[UINib nibWithNibName:@"MyNib" bundle:nil];
[UIImage imageNamed:@"MyImage"];
[[UIViewController alloc] initWithNibName:@"MyNib" bundle:nil];

有没有办法在编译时检查这些文件引用是否有效?

经常使用上述方法后,我最终更改了引用文件的名称,但忘记更改代码中的名称。 一切都符合要求,没有问题,只有当您碰巧转到访问此文件的应用程序部分时,错误才会暴露出来。

人们是否有其他方法或技术来避免此类错误?
通过字符串引用文件名感觉非常脆弱。

ios objective-c xcode clang
4个回答
4
投票

警告:这个答案大部分已经过时了。总体思路很好,但现在存在更好的解决方案(例如,使用 SwiftGen 脚本生成枚举的图像资源)。

Nib 通常有一个与文件同名的类,例如

[[MyViewController alloc] initWithNibName:NSStringFromClassName([MyViewController class]) bundle:nil];

我通常将其隐藏到控制器的

init
方法中,作为
[self class]

对于图像加载,编译时检查很困难。帮助自己使用宏,首先用一个简单的宏替换加载方法,例如

#define LOAD_IMAGE(__IMAGE_NAME__) [UIImage imageNamed:__IMAGE_NAME__]

您应该做的第一件事是将

assert
放入此宏中,并始终检查图像是否已成功加载。这不是编译时检查,但有助于查找丢失的资源。

第二件事是编写一个 ruby/python/shell/(任何脚本语言)脚本,它将在源文件中搜索

LOAD_IMAGE
并检查该文件(括号之间)是否存在。作为 shell 脚本,它会非常简单(例如使用
grep
)。您可以将此脚本添加到您的 xcode 项目中以在编译时运行。 不要忘记检查 xibs 引用的图像。

但是,通常您必须动态创建图像名称,例如

NSString* imageName = [NSString stringWithFormat:@"image_%i", index]
。您无法在编译时检查这一点。

另外不要忘记进行反向检查 - 不要包含未在任何地方使用的图像文件。


3
投票

自动完成

[UIImage imageNamed:]
,作者:Kent Sutherland。
这在 Xcode 中提供了代码完成支持——一段出色的代码。 这在 Xcode 4.6 中对我有用:enter image description here

目前该项目不支持

imageNamed:
以外的字符串。 为了支持这些,我将尝试编写一个编译时脚本。 或者也许我会变得大胆并尝试扩展萨瑟兰先生的精彩作品。


1
投票

Xcode 不支持此功能,但如果这个问题确实困扰着您,那么您可以使用以下 hack:

  • 为每个捆绑内文件指定一个唯一的前缀(例如 app__)
  • 将文件添加到项目时,请确保首先重命名它以添加此前缀。
  • 您的编译时(预分发)检查分为两部分:1)搜索所有 .m 文件并枚举以前缀开头的字符串。您不必检查字符串是否被引号引起来,因为您的前缀是唯一的。 2) grep project.pbxproj 对于每个字符串来检查它是否包含在捆绑包中。

通过一些努力,这个过程可以大部分自动化并且也可以优化,但是上面的方法应该有效。


1
投票

这是我们使用的 bash 脚本,它列出了磁盘上但未在代码中引用的所有图像。 https://gist.github.com/3750087

可能很容易逆转这一点以检查非扩展图像和 xib。 无论如何,脚本应该是一个很好的起点

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.