简体   繁体   English

Swift 5.1 运行时如何与旧版本的 iOS 配合使用?

[英]How does Swift 5.1 runtime work with older versions of iOS?

About a year ago, if you wanted to use Swift 4.2 for iOS development, you would have to install Xcode 10, which meant that you used iOS 12 SDK.大约一年前,如果您想使用 Swift 4.2 进行 iOS 开发,则必须安装 Xcode 10,这意味着您使用的是 iOS 12 SDK。 As part your apps deployment, Swift 4.2 runtime would automatically be bundled with your app binary.作为您的应用程序部署的一部分,Swift 4.2 运行时将自动与您的应用程序二进制文件捆绑在一起。 This would mean that user installing your app would essentially download a copy of that Swift runtime that will enable your app work.这意味着安装您的应用程序的用户本质上会下载该 Swift 运行时的副本,这将使您的应用程序能够正常工作。

However, ABI stability came with Swift 5, and you no longer needed to bundle a runtime if your deployment target was iOS 12.2, since the runtime was now part of that iOS version.但是,ABI 稳定性随 Swift 5 一起提供,如果您的部署目标是 iOS 12.2,您不再需要捆绑运行时,因为运行时现在是该 iOS 版本的一部分。 However, if you wanted to support iOS 10 and iOS 11, this Swift runtime would still be bundled with your app binary, and it would behave the same way as described above.但是,如果您想支持 iOS 10 和 iOS 11,此 Swift 运行时仍将与您的应用程序二进制文件捆绑在一起,并且其行为方式与上述相同。

Documentation on swift.org states the same: swift.org上的文档说明相同:

Apps deploying back to earlier OS releases will have a copy of the Swift runtime embedded inside them.部署回早期操作系统版本的应用程序将在其中嵌入 Swift 运行时的副本。 Those copies of the runtime will be ignored — essentially inert — when running on OS releases that ship with the Swift runtime.当在 Swift 运行时附带的 OS 版本上运行时,这些运行时的副本将被忽略——本质上是惰性的。

So far so good.到现在为止还挺好。 If you use Xcode 10.2 with Swift 5.0, and you deploy your app to older iOS releases, you will still bundle Swift 5.0 runtime with it.如果您将 Xcode 10.2 与 Swift 5.0 一起使用,并将您的应用程序部署到较旧的 iOS 版本,您仍将与 Swift 5.0 运行时捆绑在一起。 Then, if your app is running on iOS 12, app will use the runtime provided by the iOS, and if it's running on eg iOS 11, it would use the runtime that was bundled as part of the app binary.然后,如果您的应用程序在 iOS 12 上运行,应用程序将使用 iOS 提供的运行时,如果它在 iOS 11 上运行,它将使用作为应用程序二进制文件的一部分捆绑的运行时。 Now the first question: Is that a correct assumption?现在第一个问题:这是一个正确的假设吗?

Now we come to Swift 5.1 and iOS 13 that will be released in September.现在我们来看看将于 9 月发布的 Swift 5.1 和 iOS 13。 Swift 5.1 includes some additional runtime features, eg opaque result types, which require Swift 5.1 runtime. Swift 5.1 包括一些额外的运行时特性,例如不透明的结果类型,这需要 Swift 5.1 运行时。

In WWDC 2019 session 402 "What's New in Swift", the speaker, when discussing the Swift 5.1 feature Opaque Result Type (SE-0244), mentions that the feature will only work on new OSes:在 WWDC 2019 会议 402“Swift 的新特性”中,演讲者在讨论 Swift 5.1 功能不透明结果类型 (SE-0244) 时提到该功能仅适用于新操作系统:

Requires new Swift runtime support需要新的 Swift 运行时支持

Available on macOS Catalina, iOS 13, tvOS 13, watchOS 6 and later适用于 macOS Catalina、iOS 13、tvOS 13、watchOS 6 及更高版本

This is the confusing part for me.这对我来说是令人困惑的部分。 Wouldn't Swift runtime 5.1 be shipped with your app regardless if you support older iOS versions (eg iOS 10 as well), thus enabling it to use these new runtime features or am I just not understanding this correctly?无论您是否支持较旧的 iOS 版本(例如 iOS 10),Swift 运行时 5.1 都不会随您的应用一起提供,从而使其能够使用这些新的运行时功能,还是我只是没有正确理解这一点?

Now the first question: Is that a correct assumption?现在第一个问题:这是一个正确的假设吗?

Yes, that is correct.对,那是正确的。

Wouldn't Swift runtime 5.1 be shipped with your app regardless if you support older iOS versions (eg iOS 10 as well), thus enabling it to use these new runtime features or am I just not understanding this correctly?无论您是否支持较旧的 iOS 版本(例如 iOS 10),Swift 运行时 5.1 都不会随您的应用一起提供,从而使其能够使用这些新的运行时功能,还是我只是没有正确理解这一点?

The embedded runtime is not exactly the same runtime as the one found in your OS.嵌入式运行时与您的操作系统中的运行时并不完全相同。 Eg the runtime in your OS is tightly integrated:例如,您操作系统中的运行时是紧密集成的:

By being in the OS, the Swift runtime libraries can be tightly integrated with other components of the OS, particularly the Objective-C runtime and Foundation framework.通过在操作系统中,Swift 运行时库可以与操作系统的其他组件紧密集成,尤其是 Objective-C 运行时和 Foundation 框架。 The OS runtime libraries can also be incorporated into the dyld shared cache so that they have minimal memory and load time overhead compared to dylibs outside the shared cache.操作系统运行时库也可以合并到 dyld 共享缓存中,这样与共享缓存外的 dylib 相比,它们的内存和加载时间开销最小。

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

Of course, the embedded runtime cannot be tightly integrated into older systems.当然,嵌入式运行时无法紧密集成到旧系统中。 The embedded runtime can only support features that were already possible on the current system it is being executed.嵌入式运行时只能支持正在执行的当前系统上已经可以使用的功能。 Features that require a newer systems are simply not present when your app runs on an older one.当您的应用程序在旧系统上运行时,需要更新系统的功能根本不存在。

Note that this has never been different for ObjC.请注意,这对于 ObjC 来说从未有过不同。 If a class or a method only exists starting with a certain OS version, you can still deploy backwards to older system versions but then you cannot use that class/method there as it simply doesn't exist.如果某个类或方法仅从某个操作系统版本开始存在,您仍然可以向后部署到较旧的系统版本,但是您不能在那里使用该类/方法,因为它根本不存在。

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

or in Swift:或在斯威夫特:

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

Just like with ObjC, new Swift features will only be available for new OSes from now on.就像 ObjC 一样,新的 Swift 功能从现在开始只适用于新的操作系统。 Only if it is possible to make these features also available for older OSes, regardless if these shipped a runtime or need to use the embedded one, this feature may also deploy backwards, though not necessarily all the way.仅当可以使这些功能也可用于较旧的操作系统时,无论它们是否提供运行时或需要使用嵌入式运行时,此功能也可能向后部署,尽管不一定完全如此。

Eg 10.15 introduces a new feature in its bundled runtime, then maybe this feature can also be made available for 10.14 and 10.13 using a shim library but not for 10.12 down to 10.9, then this feature will be tagged as "Requiring macOS 10.13 or newer".例如 10.15 在其捆绑的运行时中引入了一个新功能,那么也许这个功能也可以使用 shim 库在 10.14 和 10.13 中可用,但不适用于 10.12 到 10.9,那么此功能将被标记为“需要 macOS 10.13 或更高版本” .

If you deploy to 10.15, nothing has to be done, as the runtime of 10.15 supports the feature.如果您部署到 10.15,则无需执行任何操作,因为 10.15 的运行时支持该功能。 If you deploy to 10.14 or 10.13, then the compiler will add shim library (like it would add an embedded runtime) and on 10.13 and 10.14 the code in this library will be used while on 10.15 and later the code in the runtime will be used.如果您部署到 10.14 或 10.13,那么编译器将添加 shim 库(就像添加嵌入式运行时一样),并且在 10.13 和 10.14 上将使用此库中的代码,而在 10.15 和更高版本上将使用运行时中的代码. If you deploy to systems earlier than 10.13, this is okay but you must not use this feature on these systems then.如果您部署到 10.13 之前的系统,这没问题,但您不能在这些系统上使用此功能。

Of course, if a new feature can be made available even trough the embedded runtime, it can certainly also be made available using a shim library for all systems that shipped with an own runtime which just didn't support this feature, as the shim library can then use the same code that the embedded runtime uses.当然,如果即使通过嵌入式运行时也可以使新功能可用,那么当然也可以使用 shim 库为所有系统提供它,这些系统带有自己的运行时,只是不支持此功能,作为 shim 库然后可以使用嵌入式运行时使用的相同代码。

The ability to sometimes make new features available even to older systems is explained by the very last question on that page:该页面上的最后一个问题解释了有时甚至可以为旧系统提供新功能的能力:

Is there anything that can be done to allow runtime support for new Swift features to be backward deployed to older OSes?有什么办法可以让新 Swift 功能的运行时支持向后部署到旧操作系统吗?

It may be possible for some kinds of runtime functionality to be backward deployed, potentially using techniques such as embedding a “shim” runtime library within an app.某些类型的运行时功能可能会向后部署,可能会使用诸如在应用程序中嵌入“垫片”运行时库等技术。 However, this may not always be possible.然而,这可能并不总是可行的。 The ability to successfully backward-deploy functionality is fundamentally constrained by the limitations and existing bugs of the shipped binary artifact in the old operating system.成功向后部署功能的能力从根本上受到旧操作系统中所提供二进制工件的限制和现有错误的限制。 The Core Team will consider the backward deployment implications of new proposals under review on a case-by-case basis going forward核心团队将在未来逐案考虑正在审查的新提案的向后部署影响

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

About a year ago, if you wanted to use Swift 4.2 for iOS development, you would have to install Xcode 10, which meant that you used iOS 12 SDK.大约一年前,如果要使用Swift 4.2进行iOS开发,则必须安装Xcode 10,这意味着您使用的是iOS 12 SDK。 As part your apps deployment, Swift 4.2 runtime would automatically be bundled with your app binary.作为应用程序部署的一部分,Swift 4.2运行时将自动与您的应用程序二进制文件捆绑在一起。 This would mean that user installing your app would essentially download a copy of that Swift runtime that will enable your app work.这意味着安装您的应用程序的用户实际上将下载该Swift运行时的副本,该副本将使您的应用程序能够正常工作。

However, ABI stability came with Swift 5, and you no longer needed to bundle a runtime if your deployment target was iOS 12.2, since the runtime was now part of that iOS version.但是,Swift 5附带了ABI稳定性,并且如果您的部署目标是iOS 12.2,则不再需要捆绑运行时,因为运行时现在是该iOS版本的一部分。 However, if you wanted to support iOS 10 and iOS 11, this Swift runtime would still be bundled with your app binary, and it would behave the same way as described above.但是,如果您想支持iOS 10和iOS 11,则该Swift运行时仍将与您的应用程序二进制文件捆绑在一起,并且其行为方式与上述相同。

Documentation on swift.org states the same: swift.org上的文档说明了相同的内容:

Apps deploying back to earlier OS releases will have a copy of the Swift runtime embedded inside them.部署回早期OS版本的应用程序将在其中嵌入Swift运行时的副本。 Those copies of the runtime will be ignored — essentially inert — when running on OS releases that ship with the Swift runtime.当在Swift运行时附带的OS版本上运行时,这些运行时副本将被忽略-本质上是惰性的。

So far so good.到现在为止还挺好。 If you use Xcode 10.2 with Swift 5.0, and you deploy your app to older iOS releases, you will still bundle Swift 5.0 runtime with it.如果您将Xcode 10.2与Swift 5.0结合使用,并将您的应用程序部署到较早的iOS版本,则仍将Swift 5.0运行时与其捆绑在一起。 Then, if your app is running on iOS 12, app will use the runtime provided by the iOS, and if it's running on eg iOS 11, it would use the runtime that was bundled as part of the app binary.然后,如果您的应用程序在iOS 12上运行,则该应用程序将使用iOS提供的运行时,并且如果该应用程序在例如iOS 11上运行,则它将使用捆绑在应用程序二进制文件中的运行时。 Now the first question: Is that a correct assumption?现在的第一个问题是:这是正确的假设吗?

Now we come to Swift 5.1 and iOS 13 that will be released in September.现在我们来看看将于9月发布的Swift 5.1和iOS 13。 Swift 5.1 includes some additional runtime features, eg opaque result types, which require Swift 5.1 runtime. Swift 5.1包括一些其他运行时功能,例如,不透明的结果类型,这些功能需要Swift 5.1运行时。

In WWDC 2019 session 402 "What's New in Swift", the speaker, when discussing the Swift 5.1 feature Opaque Result Type (SE-0244), mentions that the feature will only work on new OSes:在WWDC 2019会议402“ Swift的新增功能”中,演讲者在讨论Swift 5.1功能“不透明结果类型”(SE-0244)时,提到该功能仅适用于新的OS:

Requires new Swift runtime support需要新的Swift运行时支持

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

This is the confusing part for me.这对我来说是令人困惑的部分。 Wouldn't Swift runtime 5.1 be shipped with your app regardless if you support older iOS versions (eg iOS 10 as well), thus enabling it to use these new runtime features or am I just not understanding this correctly?无论您是否支持较旧的iOS版本(例如iOS 10),Swift Runtime 5.1都不会随您的应用一起提供,从而使它能够使用这些新的运行时功能,或者我只是不正确地理解这一点?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM