一个人炫耀什么,说明内心缺少什么 [登录·注册]

吕滔博客

首页 开发 运维 工具 摄影

String 还是 NSString

Swift TIP memory 发布于April 15, 2015 标签: Swift

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

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

原因有三。

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

其次,因为在 Swift 中 String 是 struct,相比起 NSObject 的 NSString 类来说,更切合字符串的 "不变" 这一特性。通过配合常量赋值 (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 添加这个方法。当然,还有一些其他的像 length 和 characterAtIndex: 这样的 API 也没有 String 的版本,这主要是因为 String 和 NSString 在处理编码上的差异导致的。

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

let levels = "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, 4)
levels.stringByReplacingCharactersInRange(swiftRange, withString: "AAAA")
// 输出:
// AAAAA

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

let nsRange = NSMakeRange(1, 4)
(levels as NSString).stringByReplacingCharactersInRange(
    nsRange, withString: "AAAA")

相关推荐

添加新评论

网站状态

  • 栏目分类:49个
  • 发布文章:1536篇
  • 用户评论:773条
  • 开博至今:4162天

正则速查

[abc] 匹配中括号中的单个字符,如a或b或c
[^abc] 匹配除了a、b、c等字符的其他单个字符
[a-z] 匹配一个字符范围,如a到z
[a-zA-Z] 匹配一个字符范围,如a-z 或 A-Z
^ 匹配行的开始
$ 匹配行的结束
\A 匹配一个字符串的开始
\z 匹配一个字符串的结束
. 匹配任意单个字符
\s 匹配空白字符,如空格,TAB
\S 匹配非空白字符
\d 匹配一个数字
\D 匹配非数字
\w 匹配一个字母
\W 匹配非字母
\b 匹配字符边界
(...) 引用所有括号中的内容
(a|b) a或者b
a? 零个或1个a
a* 零个或多个a
a+ 1个或多个a
a{3} 3次重复的a
a{3,} 3次或3次以上重复的a
a{3,6} 3到6次重复的a

修正符

/g 查找所有可能的匹配
/i 不区分大小写
/m 多行匹配
/s 单行匹配
/x 忽略空白模式
/e 可执行模式,PHP专有
/A 强制从目标字符串开头匹配
/D 使用$限制结尾字符,则不允许结尾有换行
/U 只匹配最近的一个字符串;不重复匹配

最新回复

  • memory: 没测试过...
  • 欧文斯: 对于多个 IP 段呢?比如超过 1000 个 IP 段,匹配速度...
  • 广州网站建设: 了解了,博客的通配符HTTPS证书
  • memory: https://medoo.lvtao.net/1.2/doc....
  • 贾彦东: medoo 在select的时候如何使用sum 比如 sel...
  • memory: 纯PHP文件末尾可以没有?>,你把报错信息发我一下。
  • bigwit: 因为七牛云的免费配额不能https,索性传到自己的vps上去算了...
  • bigwit: 我直接使用,报错啊,方便发我一份吗?
  • memory: 是完整的。这个就是一个简单的上传,你可以自己写个类似的也不难的。
  • bigwit: up.php是不是不完整,刚好我也有这样的需求,麻烦你看看
  • 广州网站建设: 学习了,已经收藏起来了
  • memory: 那就改一下 Widget_Stat 这个插件。增加个方法即可。
  • 梁兴健: 文章总浏览量可以有吗
  • memory: 怪我,写的太差。。。不易懂,,,我的错
  • 善行法脉--改变财运: 你是技术大牛。这个真的看不懂
  • memory: 这个太尴尬了,哈哈,,,那是10年的时候刚接触PHP写的一个类。...
  • 梦游者: //website : http://www.lvtao.ne...