'UTF16Index()' 或 'UTF16Index.init(encodedOffset:)' 用于支持 Xcod



我所在的开发团队同时支持 Xcode 8 和 Xcode 9。

我正在开发一个在 Xcode 8 中使用String.UTF16Index(range.location)的功能。当我升级到Xcode 9时,这导致了错误'init' is deprecated

所以在Xcode 9中,我将其更改为UTF16Index.init(encodedOffset: range.lowerBound)。但是,现在这在Xcode 8中不起作用,错误Argument labels '(encodedOffset:)' do not match any available overloads

即使我可以检查 Xcode 版本并编写不同的代码,其中一行也会在编译时失败。我该如何管理?还是我只能等到我们完全迁移到 Xcode 9?

来自 Swift 文档中的版本兼容性:

注意

当 Swift 4 编译器使用 Swift 3 代码时,它会将其语言版本标识为 3.2。因此,您可以使用条件编译块(如 #if swift(>=3.2) 来编写与多个版本的 Swift 编译器兼容的代码。

在您的情况下,那将是

#if swift(>=3.2)
let idx = String.UTF16Index(encodedOffset: range.lowerBound)
#else
let idx = String.UTF16Index(range.location)
#endif

在 Xcode 9(Swift 4 或 Swift 3.2 模式)中,只编译第一行, 在 Xcode 8 (Swift 3.1) 中,只编译了第二行。

更新:使用encodedOffset被认为是有害的,将在 Swift 5 中弃用。从 Swift 4 开始,将NSRange转换为Range<String.Index>的正确方法是

let str = "abc"
let nsRange = NSRange(location: 2, length: 1)
let sRange = Range(nsRange, in: str)

正如其他人所说,你可以做一个 Swift 版本检查来调用正确的 API。但是,如果您从多个位置调用它,那么定义填充程序可能更容易

#if swift(>=3.2)
// already correct
#else
extension String.UTF16Index {
init(encodedOffset: Int) {
self.init(encodedOffset)
}
}
#endif

现在你可以只写String.UTF16Index(encodedOffset: range.lowerBound),在 Xcode 8 中它会调用你的填充码。

最新更新