静态库iOS中的链接弱

时间:2018-06-28 00:21:09

标签: ios objective-c xcode frameworks weak-linking

我们有一个静态框架,该框架已构建,并且取决于用于访问ID的SDK。该SDK已发布了具有新界面的新版本。

当前,用户将添加我们的框架和依赖项SDK,并且一切正常。现在,我们希望用户能够添加我们的框架以及旧的或新的SDK,并且我不确定如何在不创建多个我们不希望这样做的目标的情况下执行此操作。使用我设置的方式,用户必须添加我们的SDK以及新旧SDK。

我有一个协议SDKProtocol,它由两个类NewSDKServicesOldSDKServices实现。

除非存在新的SDK,否则

NewSDKServices将不会编译,除非存在旧的SDK,否则OldSDKServices将不会编译。我认为这是可以的,因为它是一个预编译的框架,我们可以在运行时决定使用哪个框架。

然后,我希望能够执行类似的操作,也许可以使用ifdef来导入和初始化正确的服务。

if (useNewSDK) {
    _sdkService = [[NewSDKServices alloc] init];
} else {
    _sdkService = [[OldSDKServices alloc] init];
}

我已经考虑过弱地链接这些库,但是由于不能将静态链接框架静态链接到其他静态框架,因此我不确定该如何工作。我希望有个方向。

两个SDK都有一些标头和一个.a

1 个答案:

答案 0 :(得分:1)

我知道您说过您不想要两个目标。 坦白地说,这可能是最好的选择,因为您对要求很明确并且很先行,因此没有人会很容易混淆。 有很多方法可以通过重新使用源文件甚至使用您建议的方式来

if (useNewSDK) {
    _sdkService = [[NewSDKServices alloc] init];
} else {
    _sdkService = [[OldSDKServices alloc] init];
}

将是

#ifdef USE_SDK_NEW
    _sdkService = [[LinkedSDK alloc] init];
#else //USE_SDK_NEW
    _sdkService = [[LinkedSDK alloc] init];
#endif //USE_SDK_NEW 

但是...如果您真的想以其他方式做到这一点并且可以解决问题,则必须尝试使用​​弱链接。

如果使用弱链接,通常需要NSClassFromString(...)来访问内容。您可能需要确定SDK的可用性,希望有人将信息添加到了[NSClassFromString("TheSdk") performSelector: @"GetVersion"]之类的静态类中,或者使用了其他类存在或不存在的知识。如果两个版本之间的类集相同,则您将退回到查询选择器或成员。

再说一次,这还不是很漂亮。如果您熟悉并且对旧的SDK和新的SDK都有策略,可以使用策略模式来减轻它的麻烦,并尝试弱链接这些类而不会导致编译器要求它们。

如果您将自己作为pod进行分发,则可以创建两个目标,并使用该版本来区分所需的其他SDK。