String或NSString,应该是

作为一种现代编程语言, Swift在过去几年中迅速普及。 尽管在生产开发中大量采用Swift可以带来很多方面的优势,但有时仍不可避免地要与基于Objective-C的框架或库进行互操作。 例如, StringNSString ,应该采用哪个或更适合我们当前的开发?

尽可能使用本机类型

通常,您应该尽可能使用Swift本机类型,因为它们经过优化可以编译以提高性能。 但是等等,我只是说不可避免 ,对吧? 让我们以基于Objective-C的类NSRegularExpression为例。

 let str = "Hello, playground" do { let expression = try NSRegularExpression(pattern: "\\s{1,}", options: [.anchorsMatchLines]) let range = NSRange(location: 0, length: str.characters.count) let matches = expression.matches(in: str, options: [], range: range) for match in matches { print(match) } } catch { print(error.localizedDescription) } 

在上面的代码片段中,我们可以看到函数func matches(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> [NSTextCheckingResult] ,仅接受NSRange变量作为参数; 因此,将代码互操作并混合在一起使用StringNSStringRangeNSRange无疑是将Range类型的str.startIndex..<str.endIndexNSRange类的必要。 但是,经验丰富的Swift程序员可能会发现上述片段中也存在致命的缺陷。 它是关于计算字符串长度str.characters.count 。 由于Swift使用Extended Grapheme Clusters(扩展字素簇),这样的做法容易出错。 例如,Unicode笑脸符号。 Swift将其视为一个字符,但NSString方法将其视为两个字符。

所以……有原则或建议吗?

如果我们不想在这种差异上花太多的精力,那么为了无风险,我的建议是,一旦NSRegularExpression基于NSRegularExpression -C的函数(如NSRegularExpressionNSRegularExpressionNSString 。 当然,在引入本机Swift功能之前,该策略将不是必需的。 我们可能有一天会看到RegularExpression

因此,为了修复上述缺陷。 计算长度的方法应类似于以下代码段。 总而言之,总是有本地方法来处理变量。 但是,无风险或不太容易出错的策略有时可以为我们节省一天的时间🙂

 // Option 1: Cast String to NSString let range = NSRange(location: 0, length: (str as NSString).length) // Option 2: Calculate utf16 count when accessing on a Swift String value. let range = NSRange(location: 0, length: str.utf16.count)