在Xcode中,我可以将框架设置为“Optional”而不是“Required”,这意味着框架是弱链接的。
这是否意味着框架只会在某个地方导入时才会包含在捆绑包中?
我想弱连接一些使用私有API 的调试框架,我不希望它们出现在App Store版本中。
答案 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 / ...)指定,如下所示:
如果你想弱链接它,请使用-weak_framework PassKit
(PassKit,当然,这只是一个例子......插入框架的名称)。如果您的Debug框架不在默认框架目录之一中,则可能必须提供完整路径或修改框架搜索路径。另外,您应该使用宏来确保使用调试框架的任何代码都不会进入App Store构建。
修改:Xcode 5之后的另一个选择是使用@import <FrameworkName>;
。这样,您可以将“链接二进制...”阶段留空并触发代码中框架的链接。然后,您可以使用DEBUG
等宏来确保某些框架不用于App Store构建。有关@import
的{{3}}。
答案 1 :(得分:3)
我在使用iAd时遇到弱链接。问题是,如果我强大的链接iAds框架并在具有不支持iAds的SDK的设备上运行应用程序,那么它将简单地崩溃。弱链接允许避免崩溃。我仍然相信,即使是弱链接,如果框架可用,你仍然需要检查代码。
答案 2 :(得分:2)
这是否意味着框架只在某个地方导入时才包含在捆绑包中?
这取决于您配置方案或目标的方式。
您可以仅使用一种方案进行调试,并仅在那里包含可选框架。使用另一种没有可选框架发布的方案。
<强>更新强>
为此,请将新方案基于项目配置,并按照hagi's answer中的说明设置OTHER_LDFLAGS
。