是否可以强制 Xcode 编译器验证代码中引用的文件是否有效?
当您自然地通过 NSString 以编程方式引用文件时,Cocoa 开发中有多个要点:
[UINib nibWithNibName:@"MyNib" bundle:nil];
[UIImage imageNamed:@"MyImage"];
[[UIViewController alloc] initWithNibName:@"MyNib" bundle:nil];
有没有办法在编译时检查这些文件引用是否有效?
经常使用上述方法后,我最终更改了引用文件的名称,但忘记更改代码中的名称。 一切都符合要求,没有问题,只有当您碰巧转到访问此文件的应用程序部分时,错误才会暴露出来。
人们是否有其他方法或技术来避免此类错误?
通过字符串引用文件名感觉非常脆弱。
警告:这个答案大部分已经过时了。总体思路很好,但现在存在更好的解决方案(例如,使用 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]
。您无法在编译时检查这一点。
另外不要忘记进行反向检查 - 不要包含未在任何地方使用的图像文件。
[UIImage imageNamed:]
,作者:Kent Sutherland。目前该项目不支持
imageNamed:
以外的字符串。 为了支持这些,我将尝试编写一个编译时脚本。 或者也许我会变得大胆并尝试扩展萨瑟兰先生的精彩作品。
Xcode 不支持此功能,但如果这个问题确实困扰着您,那么您可以使用以下 hack:
通过一些努力,这个过程可以大部分自动化并且也可以优化,但是上面的方法应该有效。
这是我们使用的 bash 脚本,它列出了磁盘上但未在代码中引用的所有图像。 https://gist.github.com/3750087
可能很容易逆转这一点以检查非扩展图像和 xib。 无论如何,脚本应该是一个很好的起点