“弱连结”框架意味着什么?

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

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

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

重要提示 :这个答案是在iOS 8发布之前写的。 尽pipe技术细节仍然适用于系统框架,但现在可以构build自己的dynamic链接框架,这些框架在您的应用程序包中提供。 有限制,例如,只有一个应用程序,其扩展可以链接到一个embedded式框架的同一个实例,但事实是自定义,dynamic链接的框架可能的,因为iOS 8。如果你想了解更多,请参阅本指南 ( 使用embedded式框架共享代码 )和WWDC 2014会话416, 构build现代框架

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

有些框架可能并不适用于您打算支持的所有设备,例如,PassKit是在iOS 6中引入的。如果您运行的应用与iOS 5设备上的PassKit链接,则启动后会立即崩溃,因为dynamic链接程序不能在设备上find框架。 但是,如果您连接PassKit的链接太弱,那么dynamic链接程序会将所有框架的符号设置nil ,如果框架找不到的话。 这可以防止应用程序崩溃,您可以在运行时检查符号的可用性,例如:

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

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

有关弱连接的更多信息: Apple文档

要真正回答你的问题:

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

否。该框架将始终从应用程序链接。 只有在应用程序运行的实际设备上没有find框架时,框架才会被加载。

一个解决scheme是将debugging和App Store构build分开的目标。 另一种方法是不使用Xcode内置的“链接二进制与库”构build阶段,而是通过链接器选项链接debugging框架。 这些可以分别为每个configuration(Debug / Release / …)指定,如下所示:

通过链接器标志添加框架

如果你想弱链接,使用-weak_framework PassKit (当然,PassKit只是一个例子,插入你的框架的名称)。 如果您的debugging框架不在默认框架目录之一中,则可能需要提供完整path或修改“框架searchpath”。 另外,您应该使用macros来确保使用debugging框架的代码不会使其进入App Store版本。

编辑 :自Xcode 5以来的另一个select是使用@import <FrameworkName>; 。 这样,您可以将“链接二进制…”阶段留空,并触发代码中框架的链接。 然后,您可以使用诸如DEBUGmacros来确保某些框架不用于App Store构build。 关于@import有一个很好的答案 。

当我使用iAds时遇到了弱连接。 问题是,如果我强大的链接iAds框架,并运行与SDK不支持iAds的设备上运行的应用程序,那么它只会崩溃。 弱链接可以避免崩溃。 我仍然相信,即使有弱链接,如果框架是否可用,你仍然需要检查代码。

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

这取决于你如何configuration你的scheme或目标。

您只能使用一个scheme进行debugging,并且只包含您的可选框架。 使用另一个没有可选框架的scheme来发布。

方案示例

UPDATE

为此,请将您的新schemebuild立在项目configuration上,并OTHER_LDFLAGS 的答案中所述设置OTHER_LDFLAGS

项目配置和方案