5

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

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

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

在编译时有什么方法可以检查这些文件引用是否有效?

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

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

4

4 回答 4

4

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

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

[[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]. 无法在编译时检查它。

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

于 2013-01-04T19:05:37.400 回答
3

肯特萨瑟兰的自动完成功能[UIImage imageNamed:]
这在 Xcode 中提供了代码完成支持——一段出色的代码。这在 Xcode 4.6 中对我有用:在此处输入图像描述

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

于 2013-02-02T05:20:30.107 回答
1

Xcode 不支持这一点,但如果这个问题真的很困扰你,那么你可以使用以下 hack:

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

通过一些努力,这个过程可以大部分自动化和优化,但上面的方法应该可以工作。

于 2013-01-04T18:48:43.253 回答
1

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

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

于 2013-01-04T20:16:30.317 回答