0

我已经为 Objective-C 应用程序构建了一个框架。我已经在它工作的简约程序上对其进行了测试。我现在正试图在真正的应用程序中使用它。不幸的是,链接器找不到我的类的定义。=(

当我尝试运行它时,我收到以下错误消息:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_ClassInMyFramework", referenced from:
    objc-class-ref in libMyLib.a(MyLib.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

依赖关系:
App -> libMyLib.a -> MyFramework.framework

此错误消息的通常建议是将框架添加到“Link Binary with Library”构建阶段...我可以向您保证这已经发生了;)

我的第一个想法是构建设置可能有问题,导致此链接错误。再三考虑这可能与项目设置有关。是否可以将框架静态链接到“.a”库文件中?

更新:
我已经将框架链接到应用程序中,现在它可以工作了。但我不认为这是一个干净的解决方案。帮助仍然appriciated。=)

4

1 回答 1

1

简短的回答是否定的,您不能将框架静态链接到您的 .a 文件中。请参阅此讨论

原因是,静态库不包含来自动态框架的类的目标代码(定义)。静态库链接到框架中的目标代码的方式与应用程序链接到框架代码的方式相同:在运行时。

来自Apple的框架编程指南:“动态共享库具有将它们与静态链接共享库区分开来的特征。对于静态链接共享库,在链接时检查库中的符号以确保它们存在。如果它们不存在, 发生链接错误。使用动态共享库时,未定义符号的绑定会延迟到程序执行为止。”

这取决于您希望能够对您的代码做什么。您可以为您的框架项目添加一个静态“目标”,以便您的框架项目同时输出一个框架和一个静态库。您可以将此静态库包含到应用程序中。

但是,框架的一个好处是您可以包含 nib、图像、标题等。因此,将您的框架直接链接到您的应用程序并不是一个坏方法。否则,您需要将这些资产直接包含到您的项目中。如果您希望此框架与您的应用程序一起分发,您需要将其打包到应用程序包装器中。

看起来有些人创建了一个“静态框架”以包含在 iOS 项目中,但这对我来说看起来有点 hacky。

作为一个有趣的练习,您可以探索目标代码中的符号。假设您在静态库的某处使用 ClassInMyFramework(来自您的框架),例如:

ClassInMyFramework *myFramework = [[ClassInMyFramework alloc] init]; 

然后静态库将包含 _OBJC_CLASS__$_ClassInMyFramework 符号。您可以在命令行中查看静态库文件中的符号列表:

$ nm /path/to/libMyLib.a

这将输出一个符号列表,其中将显示 _OBJC_CLASS_$_ClassInMyFramework 未定义(注意,“U”表示该类未定义):

                 U _OBJC_CLASS_$_ClassInMyFramework

然而,如果您对框架上的 nm 命令执行以下操作:

$ nm /path/to/MyFramework.framework/Versions/A/MyFramework

您的输出将显示该符号已在您的框架中定义(尽管定义仍将仅在运行时链接),看起来像这样,显示定义的地址:

0000000000001100 S _OBJC_CLASS_$_ClassInMyFramework
于 2013-08-23T09:37:38.780 回答