STRING 还是 NSSTRING

既然像String这样的 Swift 的类型和 Foundation 的对应的类是可以无缝转换的,那么我们在使用和选择的时候,有没有什么需要特别注意的呢?

简单来说,没有特别需要注意的,但是尽可能的话还是使用原生的String类型。

原因有三。

首先虽然StringNsstring有着良好的互相转换的特性,但是现在 Cocoa 所有的 API 都接受和返回String类型。我们没有必要也不必给自己凭空添加麻烦去把框架中返回的字符串做一遍转换,既然 Cocoa 鼓励使用String,并且为我们提供了足够的操作String方法,那为什么不直接使用呢?

其次,因为在 Swift 中String是 struct,相比起NSObjectNsstring类来说,更切合字符串的 "不变" 这一特性。通过配合常量赋值 (let) ,这种不变性在多线程编程时就非常重要了,它从原理上将程序员从内存访问和操作顺序的担忧中解放出来。另外,在不触及Nsstring特有操作和动态特性的时候,使用String方法,在性能上也会有所提升。

最后,因为String实现了像CollectionType这样的接口,因此有些 Swift 的语法特性只有String才能使用,而Nsstring是没有的。一个典型就是for...in的枚举,我们可以写:

let levels = "ABCDE"
for i in levels {
    print(i)
}

// 输出
// ABCDE

而如果转换为Nsstring的话,是无法编译的。

不过也有例外的情况。有一些Nsstring方法String中并没有实现,一个很有用的就是在 iOS 8 中新加的containsstring。我们想使用这个 API 来简单地确定某个字符串包括一个子字符串时,只能先将其转为Nsstring

if (levels as Nsstring).containsstring("BC") {
    println("包含字符串")
}

// 包含字符串

A> Swift 的String没有containsstring是一件很奇怪的事情,理论上应该不存在实现的难度,希望只是 Apple 一时忘了这个新加的 API 吧。当然你也可以自行用扩展的方式在自己的代码库为String添加这个方法。当然,还有一些其他的像lengthcharacteratIndex:这样的 API 也没有String的版本,这主要是因为Nsstring在处理编码上的差异导致的。

使用String唯一一个比较麻烦的地方在于它和Range的配合。在Nsstring中,我们在匹配字符串的时候通常使用NSRange来表征结果或者作为输入。而在使用String的对应的 API 时,NSRange也会被映射成它在 Swift 中且对应String的特殊版本:Range<String.Index>。这有时候会让人非常讨厌:

"ABCDE"

let nsRange = NSMakeRange(1,4)
// 编译错误
// 'NSRange' is not convertible to 'Range<String.Index>'
levels.stringByReplacingCharactersInRange(nsRange,withString: "AAAA")

let indexPositionOne = levels.startIndex.successor()
let swiftRange = indexPositionOne..<advance(indexPositionOne,31)">4)
levels.stringByReplacingCharactersInRange(swiftRange,0)">"AAAA")
// AAAAA

一般来说,我们可能更愿意和基于IntNSRange一起工作,而不喜欢使用麻烦的Range<String.Index>。这种情况下,将String转为Nsstring也许是个不错的选择:

4)
(levels as Nsstring).stringByReplacingCharactersInRange(
    nsRange,0)">"AAAA")

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...