“弱链接”框架意味着什么?

时间:2013-06-04 15:41:16

标签: ios xcode frameworks weak-linking

在Xcode中,我可以将框架设置为“Optional”而不是“Required”,这意味着框架是弱链接的。

这是否意味着框架只会在某个地方导入时才会包含在捆绑包中?

我想弱连接一些使用私有API 的调试框架,我不希望它们出现在App Store版本中。

3 个答案:

答案 0 :(得分:17)

重要提示: 这个答案是在iOS 8发布之前编写的。虽然技术细节仍然适用于系统框架,但现在可以构建您自己的动态链接框架,这些框架在您的应用程序包中提供。有一些限制,例如,只有一个应用程序及其扩展可以链接到嵌入式框架的同一个实例,但事实上,自iOS 8以来,自定义动态链接框架可能。如果你想要了解更多信息,请参阅this guide使用嵌入式框架共享代码)和WWDC 2014会话416,构建现代框架

原始答案: (平台)框架中没有一个“包含在软件包中”。相反,一旦您将其添加到“带库的链接二进制”构建阶段,您的应用就会有一个引用(“ link ”)到框架。框架预先安装在设备上。当您运行应用程序时,所有应用程序的框架引用都由动态链接器(在设备上)解析,这意味着框架代码已加载,因此您的应用程序可以使用它。

有些框架可能无法在您打算支持的所有设备上使用,例如,在iOS 6中引入了PassKit。如果您在iOS 5设备上运行与PassKit链接的应用程序,它会在启动后立即崩溃,因为动态链接器无法在设备上找到框架。但是,如果您弱链接PassKit,动态链接器会将所有框架的符号设置为nil,如果找不到框架。这可以防止应用程序崩溃,您可以在运行时检查符号的可用性,例如:

if ([PKPass class]) {
  // Class is available - use it
  PKPass *pass = [[PKPass alloc] init];
}

[PKPass class]可安全地在所有设备/系统上使用,因为PKPass类符号在旧系统上为nil,而消息nil在Objective中不是问题-C。

有关弱链接的更多信息:Apple Documentation

要真正回答你的问题:

  

这是否意味着框架只在某个地方导入时才包含在捆绑包中?

否。该框架将始终从应用链接。

只有在您的应用运行的实际设备上找不到框架时,才会加载框架。

一种解决方案是为Debug和App Store Build建立单独的目标。另一种方法是不使用Xcode内置的“Link Binary with Library”构建阶段,而是通过链接器选项链接Debug框架。这些可以分别为每个配置(Debug / Release / ...)指定,如下所示:

Adding framework via linker flags

如果你想弱链接它,请使用-weak_framework PassKit(PassKit,当然,这只是一个例子......插入框架的名称)。如果您的Debug框架不在默认框架目录之一中,则可能必须提供完整路径或修改框架搜索路径。另外,您应该使用宏来确保使用调试框架的任何代码都不会进入App Store构建。

修改:Xcode 5之后的另一个选择是使用@import <FrameworkName>;。这样,您可以将“链接二进制...”阶段留空并触发代码中框架的链接。然后,您可以使用DEBUG等宏来确保某些框架不用于App Store构建。有关@import的{​​{3}}。

答案 1 :(得分:3)

我在使用iAd时遇到弱链接。问题是,如果我强大的链接iAds框架并在具有不支持iAds的SDK的设备上运行应用程序,那么它将简单地崩溃。弱链接允许避免崩溃。我仍然相信,即使是弱链接,如果框架可用,你仍然需要检查代码。

答案 2 :(得分:2)

  

这是否意味着框架只在某个地方导入时才包含在捆绑包中?

这取决于您配置方案或目标的方式。

您可以仅使用一种方案进行调试,并仅在那里包含可选框架。使用另一种没有可选框架发布的方案。

Scheme Example

<强>更新

为此,请将新方案基于项目配置,并按照hagi's answer中的说明设置OTHER_LDFLAGS

Project Configurations and Schemes