“弱链接"是什么意思?一个框架? [英] What does it mean to "weak-link" a framework?

查看:29
本文介绍了“弱链接"是什么意思?一个框架?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

解决方案

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

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

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.

解决方案

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 are possible 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.

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.

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.:

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 PKPass class symbol will be nil on older systems, and messaging nil is not a problem in Objective-C.

More on Weak-Linking: Apple Documentation

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:

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.

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 DEBUG to make sure some frameworks aren't used for App Store builds. There's an excellent answer regarding @import.

这篇关于“弱链接"是什么意思?一个框架?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆