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

时间:2013-01-04 18:26:45

标签: objective-c ios xcode compiler-construction llvm-clang

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

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

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

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

经常使用上述方法后,我最终更改了引用文件的名称,但忘记在代码中更改名称。一切都顺从,没有问题,只有当你碰巧去访问该文件的应用程序部分时,bug才会显露出来。

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

4 个答案:

答案 0 :(得分:3)

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]。在编译时你无法检查这个问题。

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

答案 1 :(得分:3)

Kent Sutherland的

AutoComplete for [UIImage imageNamed:] 这为Xcode提供了代码完成支持 - 一段精彩的代码。这在Xcode 4.6中适用于我:enter image description here

目前,此项目不支持imageNamed:以外的字符串。为了支持这些,我将尝试编写一个编译时脚本。或许我会变得大胆并试图延伸萨瑟兰先生的壮观作品。

答案 2 :(得分:1)

Xcode不支持这个,但如果这个问题真的让你感到困惑,那么你可以使用以下hack:

  • 为每个in-bundle文件提供唯一的前缀(例如app __)
  • 向项目添加文件时,请确保先重命名该文件以添加此前缀。
  • 您的编译时间(预分发)检查有两部分:1)搜索所有.m文件并枚举以前缀开头的字符串。您不必检查字符串是否被引用,因为您的前缀是唯一的。 2)grep project.pbxproj为每个字符串检查它是否包含在包中。

通过一些努力,这个过程可以大部分是自动化的,也可以进行优化,但上述配方应该有效。

答案 3 :(得分:1)

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

可能很容易将其反转以检查不存在的图像和xib。 无论如何,脚本应该是一个很好的起点