xcode “弱链接”一个框架是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16922013/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 03:26:56  来源:igfitidea点击:

What does it mean to "weak-link" a framework?

iosxcodeframeworksweak-linking

提问by openfrog

In Xcode, I can set a framework to "Optional" instead of "Required", which then means the framework is weak linked.

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

Does that mean the framework is only included in the bundle when it is imported somewhere?

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

I want to weak-link a few debugging frameworks which use private API, and I do not want them to appear in the App Store build.

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

回答by hagi

Important note: This answer was written before iOS 8 was announced. While the technical details still apply to system frameworks, it is now possible to build your own, dynamically linked frameworks that ship within your app bundle. There are restrictions, e.g., only an app and its extensions can link to the same instance of an embedded framework, but the fact remains that custom, dynamically linked framework arepossible since iOS 8. If you want to learn more, refer to this guide(Using an Embedded Framework to Share Code) and WWDC 2014 session 416, Building Modern Frameworks.

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

Original Answer: None of the (platform) frameworks is really "included in the bundle". Instead, your app has a reference ("link") to a framework once you add it to the "Link Binary with Library" build phase. The frameworks are pre-installed on the devices. When you run an app, all the app's framework references are resolved by the dynamic linker (on the device), which means the framework code is loaded so your app can use it.

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

Some frameworks may not be available on all the devices you intend to support, e.g., PassKit was introduced in iOS 6. If you run an app that links against PassKit on an iOS 5 device, it crashes right after launch, because the dynamic linker cannot find the framework on the device. However, if you weak-link PassKit, the dynamic linker will set all the framework's symbols to nil, if the framework could not be found. This prevents the app from crashing and you can check for the symbols' availability at runtime, e.g.:

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

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

[PKPass class]is safe to use on all devices/systems since the PKPassclass symbol will be nilon older systems, and messaging nilis not a problem in Objective-C.

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

More on Weak-Linking: Apple Documentation

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

To really answer your question:

真正回答你的问题:

Does that mean the framework is only included in the bundle when it is imported somewhere?

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

No.The framework will always be linked from the app. Only when the framework is not found on the actual device your app is running on, then the framework will not be loaded.

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

One solution would be to have separate targets for Debug and App Store Builds. An alternative is to not use the built-in "Link Binary with Library" build phase from Xcode, but to link the Debug frameworks via linker options. These can be specified for each configuration (Debug/Release/...) separately, like so:

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

Adding framework via linker flags

通过链接器标志添加框架

If you'd want to weak-link it, use -weak_framework PassKit(PassKit, of course, being just an example here... insert the name of your framework) instead. If your Debug framework is not in one of the default framework directories, you might have to provide a full path or modify the Frameworks Search Path. Plus, you should probably use macros to make sure none of the code using the debug framework(s) makes it to the App Store build.

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

Edit: Another option since Xcode 5 is to use @import <FrameworkName>;. This way, you can leave your "Link Binary..." phase empty and trigger the linking of frameworks in code. You can then use macros such as DEBUGto make sure some frameworks aren't used for App Store builds. There's an excellent answerregarding @import.

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

回答by azamsharp

I encountered weak linking when I was using iAds. The problem was if I strong link iAds framework and run the app on a device with SDK which did not supported iAds then it will simply crash. Weak linking allowed to avoid the crashes. I still believe that even with weak linking you still have to check in code if the framework is available or not.

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

回答by mkalmes

Does that mean the framework is only included in the bundle when it is imported somewhere?

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

This depends on how you configured your schemes or targets.

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

You could use one scheme only for debugging and include your optional framework only there. Use another scheme without the optional framework for release.

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

Scheme Example

方案示例

UPDATE

更新

To do this, base your new scheme on a project configuration and set OTHER_LDFLAGSas described in hagi's answer.

为此,请将您的新方案基于项目配置并OTHER_LDFLAGS按照hagi 的回答中所述进行设置。

Project Configurations and Schemes

Project Configurations and Schemes