Swift 5.1运行时如何与旧版iOS一起使用?

时间:2019-08-25 19:00:17

标签: ios swift xcode abi

大约一年前,如果要使用Swift 4.2进行iOS开发,则必须安装Xcode 10,这意味着您使用的是iOS 12 SDK。作为应用程序部署的一部分,Swift 4.2运行时将自动与应用程序二进制文件捆绑在一起。这意味着安装您的应用的用户实际上会下载该Swift运行时的副本,从而使您的应用能够正常工作。

但是,Swift 5附带了ABI稳定性,如果您的部署目标是iOS 12.2,则不再需要捆绑运行时,因为该运行时现在是该iOS版本的一部分。但是,如果您想支持iOS 10和iOS 11,则该Swift运行时仍将与您的应用二进制文件捆绑在一起,并且其行为方式与上述相同。

swift.org上的文档说明相同:

  

部署回早期OS版本的应用程序将在其中嵌入Swift运行时的副本。当在Swift运行时附带的OS版本上运行时,这些运行时副本将被忽略-本质上是惰性的。

到目前为止,一切都很好。如果您将Xcode 10.2与Swift 5.0结合使用,并将您的应用程序部署到较早的iOS版本,您仍将捆绑Swift 5.0运行时。然后,如果您的应用程序在iOS 12上运行,则该应用程序将使用iOS提供的运行时,并且例如在Windows 10上运行。 iOS 11将使用捆绑在应用程序二进制文件中的运行时。现在的第一个问题是:这是正确的假设吗?

现在,我们来看看将于9月发布的Swift 5.1和iOS 13。 Swift 5.1包含一些其他运行时功能,例如不透明的结果类型,需要Swift 5.1运行时。

在WWDC 2019会议402“ Swift的新增功能”中,演讲者在讨论Swift 5.1功能“不透明结果类型”(SE-0244)时,提到该功能仅适用于新的操作系统:

  

需要新的Swift运行时支持

     

在macOS Catalina,iOS 13,tvOS 13,watchOS 6和更高版本上可用

这对我来说是令人困惑的部分。无论您是否支持较旧的iOS版本(例如iOS 10),Swift Runtime 5.1都不会随您的应用一起提供,从而使它能够使用这些新的运行时功能,或者我只是不正确地理解这一点?

2 个答案:

答案 0 :(得分:0)

<块引用>

现在第一个问题:这是一个正确的假设吗?

是的,没错。

<块引用>

无论您是否支持较旧的 iOS 版本(例如 iOS 10),Swift 运行时 5.1 都不会随您的应用一起提供,从而使其能够使用这些新的运行时功能,还是我只是没有正确理解这一点?

嵌入式运行时与您的操作系统中的运行时并不完全相同。例如。您操作系统中的运行时紧密集成:

<块引用>

通过在操作系统中,Swift 运行时库可以与操作系统的其他组件紧密集成,尤其是 Objective-C 运行时和 Foundation 框架。操作系统运行时库也可以合并到 dyld 共享缓存中,这样与共享缓存外的 dylib 相比,它们的内存和加载时间开销最小。

来源:https://swift.org/blog/abi-stability-and-apple/

当然,嵌入式运行时无法紧密集成到旧系统中。嵌入式运行时只能支持正在执行的当前系统上已经可以使用的功能。当您的应用在旧系统上运行时,需要更新系统的功能根本不存在。

请注意,这对于 ObjC 来说从未有过不同。如果某个类或方法仅从某个操作系统版本开始存在,您仍然可以向后部署到较旧的系统版本,但是您不能在那里使用该类/方法,因为它根本不存在。

if (@available(iOS 13, *)) {
    // Code requiring iOS 13
} else {
    // Alternative code for older OS versions
}

或在 Swift 中:

if #available(iOS 13, *) {
    // Code requiring iOS 13
} else {
    // Alternative code for older OS versions
}

就像 ObjC 一样,新的 Swift 功能从现在开始只适用于新的操作系统。仅当可以使这些功能也适用于较旧的操作系统时,无论它们是否提供运行时或需要使用嵌入式运行时,此功能也可以向后部署,尽管不一定完全如此。

例如10.15 在其捆绑的运行时中引入了一个新功能,那么也许这个功能也可以使用 shim 库在 10.14 和 10.13 中可用,但不适用于 10.12 到 10.9,那么此功能将被标记为“需要 macOS 10.13 或更高版本”。

如果您部署到 10.15,则无需执行任何操作,因为 10.15 的运行时支持该功能。如果您部署到 10.14 或 10.13,那么编译器将添加 shim 库(就像添加嵌入式运行时一样),并且在 10.13 和 10.14 上将使用此库中的代码,而在 10.15 和更高版本上将使用运行时中的代码.如果您部署到 10.13 之前的系统,这是可以的,但您不能在这些系统上使用此功能。

当然,如果即使通过嵌入式运行时也可以使新功能可用,那么当然也可以使用 shim 库为所有系统提供它,这些系统带有自己的运行时,只是不支持此功能,如然后,shim 库可以使用嵌入式运行时使用的相同代码。

该页面的最后一个问题解释了有时甚至可以为旧系统提供新功能的能力:

<块引用>

有什么办法可以让运行时支持将新的 Swift 功能向后部署到旧的操作系统?

某些类型的运行时功能可以向后部署,可能会使用诸如在应用中嵌入“垫片”运行时库等技术。然而,这可能并不总是可行的。成功向后部署功能的能力从根本上受到旧操作系统中所提供二进制工件的限制和现有错误的限制。核心团队将在未来逐案考虑正在审查的新提案对向后部署的影响

来源:https://swift.org/blog/abi-stability-and-apple/

答案 1 :(得分:-3)

除非我没有记错,否则语言swift 3或5在这件事上都没有关系,因为它是经过编译的,这就有点像您决定使用C ++或Objective-c而不是swift一样。是您的Xcode版本可以部署在所需的Ios版本上。