【问题标题】:Linker Error: iPhone Unit Test Bundle referencing App classes链接器错误:引用 App 类的 iPhone 单元测试包
【发布时间】:2026-02-18 19:15:02
【问题描述】:

从一个已经在开发中的应用开始,我已经按照 iPhone 开发指南 – 单元测试应用程序中的说明进行操作

我可以成功地在设备上运行的应用程序样式测试中包含和使用我的应用程序类,并将其结果输出到控制台。

如果我添加以下代码行:

STAssertTrue([viewController isKindOfClass:[LoginViewController class]], @"Top view controller is not LoginViewController");

生成以下构建错误:

Undefined symbols:
  "_OBJC_CLASS_$_LoginViewController", referenced from:
      __objc_classrefs__DATA@0 in LoginViewTest.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

我可以为项目和测试目标提供更多配置信息,但安装工作文件在测试源中没有[LoginViewController class] 行。

没有那行,我可以引用该类,使用它的属性并成功地向它发送消息。

在尝试以这种方式使用 App 类时,是否需要链接构建设置或捆绑加载选项?或者我应该找到另一种类型的测试来确认对象的类是预期的吗?

【问题讨论】:

    标签: iphone unit-testing xcode linker


    【解决方案1】:

    我找到了答案,但我认为一定有“更好”的方法?

    在单元测试包的构建配置中,您可以指定指向“主机”应用的 Bundle Loader (BUNDLE_LOADER) 设置。

    ${TARGET_BUILD_DIR}/AppName.app/AppName
    

    单元测试包正在构建为您的应用程序单元测试目标的依赖项(例如,AppName Testing),因此我无法比上述更好地解析应用程序可执行文件。

    最终结果是注入到测试目标的工作单元测试没有任何链接器错误。测试按预期运行并访问类。

    编辑:Bundle Loader – 目标配置

    将“托管”测试包的目标配置为隐藏其符号非常重要。

    GCC_SYMBOLS_PRIVATE_EXTERN = NO
    

    又名。 “默认隐藏符号”。来自文档:

    启用后,所有符号都被声明 'private extern' 除非明确 标记为导出使用 '__attribute__((visibility("default")))' 在代码中。如果未启用,则所有符号 除非明确标记,否则将被导出 作为'private extern'

    有关详细信息,请参阅 http://developer.apple.com/documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html.

    【讨论】:

    • 这为我指明了正确的方向,谢谢。我的问题是我更改了主目标中的“产品名称”,因此我必须更新测试目标中的“Bundle Loader”。
    • 很好的答案,非常感谢。在现有项目上设置测试时不是很直观。无论如何它现在正在工作!另外,我花了一段时间才找到 Bundle Loader 设置,确保在 Build Settings 顶部选中“All”而不是“Basic”
    • 呃,终于。我做了同样的事情并且知道发生了什么,但我终生无法找到该死的构建设置来修复它。非常感谢。
    【解决方案2】:

    我刚刚在这里回答了这个问题:

    iPhone unit testing: Symbols not found when calling custom code

    我想其中一个应该作为副本关闭?我没有足够的声誉这样做......


    我还关注了 Apple 的 iPhone 单元测试应用程序文档,并在尝试对我的一个类进行单元测试时看到了类似于问题中描述的链接错误。

    看起来像您的单元测试类中引用的任何类,因此从您的测试目标运行也需要添加到该测试目标。为此,您可以右键单击您的 RootViewController 类并单击“获取信息”(Cmd-i 快捷方式)。在目标窗格上,确保选中您的单元测试目标(例如“LogicTests”,如果您遵循该文档中的命名)。

    现在该类将与您的测试一起编译,并且应该可用于您的单元测试。要仔细检查,请在左侧的“组和文件”浏览器中展开“目标/逻辑测试/编译资源”节点。这列出了构建目标时可用的所有类文件,现在应该包括您的单元测试类和您的测试类。

    (请注意,当您创建新应用程序或测试类时,您需要类似地选择所有适当的目标 - 命名文件时在“新建文件...”窗口的同一页面上)。

    (顺便说一下,我使用的是 XCode 3.2.3 和 OS 4.0)。

    【讨论】:

    • 您的笔记基本没问题。但他们没有解决我提出的问题。我的问题和答案涉及链接时注入的单元测试包中可用的符号。这也是您链接到的其他问题所指示的错误。您的回答是设置“测试”目标的重要部分,但在我们的两种情况下都没有造成任何问题。
    最近更新 更多