【问题标题】:What does it mean to "weak-link" a framework?“弱链接”框架是什么意思?
【发布时间】:2013-05-31 02:17:54
【问题描述】:

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

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

我想弱链接一些使用 私有 API 的调试框架,并且我不希望它们出现在 App Store 构建中。

【问题讨论】:

    标签: ios xcode frameworks weak-linking


    【解决方案1】:

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

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

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

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

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

    更多关于弱链接:Apple Documentation

    真正回答你的问题:

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

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

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

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

    编辑:自 Xcode 5 以来的另一个选项是使用 @import <FrameworkName>;。这样,您可以将“链接二进制...”阶段留空并触发代码中框架的链接。然后,您可以使用诸如 DEBUG 之类的宏来确保某些框架不用于 App Store 构建。关于@import,有一个excellent answer。

    【讨论】:

    • OP 的问题表明他使用了非 Apple 框架。所以必须将框架添加到包中。
    • 我不确定是否有框架可以,但不能动态链接,因为它们是私有的?如果框架是静态链接的,那么弱链接根本就不适用/没有任何意义。
    • Apple 没有提供官方的方式来构建框架,但这也不是不可能的。 Google 为他们的Google+ iOS SDK 提供了一个框架。 OP 的问题标题和描述不太匹配。我认为他对省略调试框架比对“弱链接”更感兴趣。
    • 我同意......弱链接关键字在这里让我走错了方向,因为我假设它是关于动态链接框架的。我知道自定义框架,但这些也是静态链接的。它基本上是一个静态库加资源。
    • 这是一个很好的答案,这个问题在许多其他地方都回答得很糟糕。如果可以的话,我会为你 +10。
    【解决方案2】:

    我在使用 iAds 时遇到了弱链接。问题是,如果我强链接 iAds 框架并在具有不支持 iAds 的 SDK 的设备上运行该应用程序,那么它只会崩溃。允许弱链接以避免崩溃。我仍然相信,即使使用弱链接,您仍然必须检查框架是否可用。

    【讨论】:

    • 好的,所以弱链接仍然包含使用私有 API 的调试框架,因此 Apple 仍然会拒绝该应用程序。
    • 私有 api 对苹果来说是不行的。因此,您的应用程序被捕获和拒绝的可能性很高。 azamsharp 答案是正确的。几天前我遇到了这个问题。
    【解决方案3】:

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

    这取决于您如何配置方案或目标。

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

    更新

    为此,请将您的新方案基于项目配置并设置OTHER_LDFLAGS,如hagi's answer 中所述。

    【讨论】:

    • 一个方案,还是我需要创建一个全新的目标来安全地排除框架?
    • 我怎样才能通过一个方案来实现这一点?链接框架部分绑定到目标/项目?
    • 您可以基于项目配置的方案并使用@hagi 的解释来相应地设置OTHER_LDFLAGS。
    猜你喜欢
    • 2011-07-05
    • 2018-03-12
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多