Swift - which types to use? NSString or String

With the introduction of Swift I've been trying to get my head round the new language

I'm an iOS developer and would use types such as NSString, NSInteger, NSDictionary in an application. I've noticed that in the "The Swift Programming Language" ebook by Apple, they use the Swift types String, Int, Dictionary

I've noticed the Swift types don't have (or are differently named) some of the functions that the Foundation types do. For example NSString has a length property. But I've not been able to find a similar one for the Swift String.

I'm wondering, for an iOS application should I still be using the Foundation types?

69991 次浏览

您应该尽可能使用 Swift 本机类型。对语言进行了优化以使用它们,并且大多数功能在本机类型和 Foundation类型之间建立了桥梁。

虽然 StringNSString基本上是可互换的,也就是说,您可以将 String变量传递到采用 NSString参数的方法中,反之亦然,但是一些方法似乎在此刻还没有被自动桥接。有关如何获取字符串长度的讨论,请参见 这个答案,有关使用 containsString()检查子字符串的讨论,请参见 这个答案。(免责声明: 我是这两个答案的作者)

我还没有完全探索其他的数据类型,但是我假设上面提到的一些版本也适用于 Array/NSArrayDictionary/NSDictionary,以及 Swift 和 NSNumber中的各种数字类型

Whenever you need to use one of the Foundation types, you can either use them to type variables/constants explicitly, as in var str: NSString = "An NSString" or use bridgeToObjectiveC() on an existing variable/constant of a Swift type, as in str.bridgeToObjectiveC().length for example. You can also cast a String to an NSString by using str as NSString.

然而,这些技术明确使用 Foundation 类型的必要性,或者至少其中的一些,在将来可能会过时,因为从语言参考中所陈述的来看,例如,String/NSString桥应该是完全无缝的。

关于这个主题的详细讨论,请参阅 与 Cocoa 和 Objective-C 一起使用 Swift: 使用 Cocoa 数据类型

由于目标 C 类型仍然是动态调度的,因此它们可能会更慢。我认为最好使用 Swift 本机类型,除非您需要与 Objective-c API 交互

StringNSString是可互换的,所以你用哪一个并不重要。您总是可以在两者之间进行强制转换,使用

let s = "hello" as NSString

甚至

let s: NSString  = "hello"

NSInteger只是 intlong的别名(取决于架构) ,所以我只使用 Int

NSDictionary是另一回事,因为 Dictionary是一个完全独立的实现。

一般来说,只要有可能,我就坚持使用快速类型,并且您总是可以在需要的时候使用快速类提供的 bridgeToObjectiveC()方法在两者之间进行转换。

尽可能使用 Swift 本机类型。但是,对于 String,您可以像下面这样“无缝”访问所有 NSString方法:

var greeting = "Hello!"
var len = (greeting as NSString).length

您最好的选择是使用 Swift 本机类型和类,正如其他一些人指出的那样,NSString 可以免费转换为 String,但是,它们并不是100% 相同的,例如下面的例子

var nsstring: NSString = "\U0001F496"
var string: String = "\U0001F496"


nsstring.length
count(string)

您需要使用 count ()方法来计算字符串中的字符数,还要注意 nsstring.length 返回2,因为它基于 UTF16计算其长度。

相似,是的 The same, NO

NSString: 创建驻留在堆中并总是通过引用传递的对象。

String: 无论何时传递它,它都是一个值类型,通过值传递。 像 Struct 和 Enum 一样,在 Swift 中字符串本身也是一个 Struct。

public struct String {
// string implementation
}

但是传递时不创建复制,而是在第一次变异时创建复制。

String 作为 NSString 自动连接到 Objective-C。如果没有 Swift Standard Library,则需要导入 Foundation 框架来访问由 NSString 定义的方法。

Swift String 非常强大,它有大量的内置函数。

字符串初始化:

var emptyString = ""             // Empty (Mutable)
let anotherString = String()     // empty String immutable
let a = String(false)           // from boolean: "false"
let d = String(5.999)           //  "    Double "5.99"
let e = String(555)             //  "     Int "555"
// New in Swift 4.2
let hexString = String(278, radix: 18, uppercase: true) // "F8"

通过重复值创建 String:

 let repeatingString = String(repeating:"123", count:2) // "123123"

在 Swift 4-> 字符串是字符集:

现在 String 可以执行任何人都可以执行的所有操作 对 Collection 类型执行。

更多信息请参考苹果文档。

Swift 4更新

字符串在快速4中得到修订。现在你可以直接调用 count,它把字符串看作一个整体,就像一个表情符号。NSString 没有更新,而是以另一种方式计数。

var nsstring: NSString = "👩‍👩‍👧‍👦"
var string: String = "👩‍👩‍👧‍👦"


print(nsstring.length) // 11
print(string.count)    // 1

String 是一个 struct

//在迅速模组

Public 结构字符串

{

}

NSString 是一个类

// in Foundation Module

打开类 NSString: NSObject

{

}

Swift String 非常优雅,易于使用,除非您需要解析它们。索引到 Swift 字符串的整个概念简直是疯了。每当需要解析典型的 unicode 字符串时,我都会将其转换为 NSString。Swift 使得这个问题有点棘手,因为常见的“字符”整数表达式,如“’”或“ A”或“0”在 Swift 中不起作用。你必须用32,65,48。不幸的是,我不是在开玩笑!因此,我将大部分字符串解析代码放入了用 Objective-C 编写的 NSString 扩展中。

是的,我确实知道为什么斯威夫特的设计者让字符串索引变得如此疯狂: 他们希望能够将表情符号这样的多字节字符表示为单个“字符”。我的选择是让这个罕见的用例表示为多个 UTF16字符,但管他呢。