`UTF16Index()`或`UTF16Index.init(encodedOffset:)`用于Xcode 8/9支持

问题描述 投票:3回答:2

我是一个支持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?

ios swift xcode deprecated
2个回答
5
投票

来自Swift文档中的Version Compatibility

注意

当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)中只编译了第二行。

更新:使用encodedOffsetconsidered harmful并将在Swift 5中使用deprecated。从Swift 4开始,将NSRange转换为Range<String.Index>的正确方法是

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

1
投票

正如其他人所说,你可以做一个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中它会调用你的垫片。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.