Swift - 使用哪些类型? NSString 或字符串

Posted

技术标签:

【中文标题】Swift - 使用哪些类型? NSString 或字符串【英文标题】:Swift - which types to use? NSString or String 【发布时间】:2014-07-25 04:10:16 【问题描述】:

随着 Swift 的引入,我一直在尝试了解新语言

我是一名 ios 开发人员,会在应用程序中使用 NSString, NSInteger, NSDictionary 等类型。我注意到在 Apple 的“The Swift Programming Language”电子书中,他们使用了 Swift 类型String, Int, Dictionary

我注意到 Swift 类型没有(或名称不同)Foundation 类型所具有的某些功能。例如 NSString 有一个 length 属性。但我一直无法为 Swift String 找到类似的。

我想知道,对于 iOS 应用程序,我是否仍应使用 Foundation 类型?

【问题讨论】:

首选String。但是,String 的功能在 alpha 版本中仍然有点受限,所以现在NSString 将被更多地使用。我们希望他们能在 GA 之前修复 API。 另外,您可以致电countElements(str),回答您问题的特定部分。 更好,你可以调用"foo".length" directly in Swift. An implicit cast to NSString`是编译器为你添加的! @GabrielePetronella .length 对于特殊字符可能无法正常工作。如 Emoji 或占用 2 或 3 个 unicode 字符的汉字。 countElements 是正确的使用方法。 【参考方案1】:

您应该尽可能使用 Swift 原生类型。该语言已针对使用它们进行了优化,并且大部分功能都在本机类型和 Foundation 类型之间架起了桥梁。

虽然StringNSString 大部分是可互换的,即您可以将String 变量传递到采用NSString 参数的方法中,反之亦然,但目前某些方法似乎没有自动桥接。请参阅this answer 了解有关如何获取字符串长度的讨论,并参阅this answer 了解有关使用containsString() 检查子字符串的讨论。 (免责声明:我是这两个答案的作者)

我还没有完全探索过其他数据类型,但我假设上面所说的某些版本也适用于Array/NSArrayDictionary/NSDictionary,以及斯威夫特和NSNumber

当您需要使用其中一种 Foundation 类型时,您可以使用它们显式键入变量/常量,如 var str: NSString = "An NSString" 或在 Swift 类型的现有变量/常量上使用 bridgeToObjectiveC(),如 @例如 987654337@。您还可以使用str as NSStringString 转换为NSString

但是,这些技术显式使用 Foundation 类型或至少其中一些类型的必要性在未来可能会过时,因为根据语言参考中所述,String/NSString 桥,例如,应该是完全无缝的。

有关该主题的详细讨论,请参阅Using Swift with Cocoa and Objective-C: Working with Cocoa Data Types

【讨论】:

+1 引用 bridgeToObjectiveC() 并解释 NSString 和 Swift 的 String 之间的联系。 嘿 cezar,如果您想更新答案,我认为不推荐使用 bridgeToObjectiveC。 我注意到在 Swift 3 手册中,Foundation 类型是通过引用传递的,而原生类型是通过值传递的(或者类似的东西,我目前还没有完全理解)。如果您可以更新您的答案并讨论其含义,那就太好了。【参考方案2】:

由于目标 C 类型仍然是动态分派的,它们可能会更慢。我会说你最好使用 Swift 原生类型,除非你需要与 Objective-c API 交互

【讨论】:

是的,这正是答案。避免动态分派方法和对象变量访问是他们在 WWDC 上谈到的速度改进的全部原因。过去每个担心性能的人都使用 C++ 字符串和容器来获得静态调度。【参考方案3】:

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

let s = "hello" as NSString

甚至

let s: NSString  = "hello"

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

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

一般来说,只要可能,我都会坚持使用 swift 类型,您可以随时使用 swift 类提供的 bridgeToObjectiveC() 方法在需要时在两者之间进行转换。

【讨论】:

Swift 的Int 数据类型在书中被声明为与架构的字长相同。 NSInteger 的大小也和架构的字大小一样。【参考方案4】:

尽可能使用 Swift 原生类型。但是,对于 String,您可以“无缝”访问所有 NSString 方法,如下所示:

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

【讨论】:

【参考方案5】:

您最好的选择是使用 Swift 原生类型和类,正如其他人所指出的,NSString 可以免费翻译为 String,但是,它们并不是 100% 相同的,例如以下

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

nsstring.length
count(string)

你需要使用count()方法来统计字符串中的字符,还要注意nsstring.length返回2,因为它是根据UTF16来计算长度的。

类似,是的 一样的,没有

【讨论】:

【参考方案6】:

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

String:当我们传递它时,它是一个值类型,它是按值传递的。 像 Struct 和 Enum 一样,String 本身就是 Swift 中的 Struct。

public struct String 
 // string implementation 

但是当你通过时不会创建副本。当您第一次对其进行变异时,它会创建副本。

String 作为 NSString 自动桥接到 Objective-C。如果 Swift 标准库没有,则需要导入 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"

从重复值创建字符串:

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

在 Swift 4 中 -> 字符串是字符的集合:

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

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

【讨论】:

这个答案应该得到更多的支持。这是 String 和 NSString 的根本区别。在其他任何地方,它们几乎可以互换 很好的答案。价值与特别是 ref 类型的注释。【参考方案7】:

Swift 4 更新

String 在 swift 4 中得到修订。现在您可以直接调用 count 并将其视为 1 块,就像表情符号一样。 NSString 没有更新,正在以另一种方式计算。

var nsstring: NSString = "?‍?‍?‍?"
var string: String = "?‍?‍?‍?"

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

【讨论】:

NSStrings 可能不会更新以处理字素集群:它会破坏太多依赖旧行为的应用程序。此外,NSString.length 计算 UTF16 字符。【参考方案8】:

字符串是结构体

// 在 Swift 模块中

公共结构字符串

NSString 是一个类

//在基础模块中

开放类 NSString : NSObject

【讨论】:

【参考方案9】:

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

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

【讨论】:

以上是关于Swift - 使用哪些类型? NSString 或字符串的主要内容,如果未能解决你的问题,请参考以下文章

InvalidFirebaseData Swift 3 只能存储 NSNumber、NSString、NSDictionary 和 NSArray 类型的对象。

swift学习第五天:字符串

在Swift中从NSString创建NSData

又名 'NSString' 没有成员 - 斯威夫特

无法使用类型为“(NSURL,*:NSString?)”的参数列表调用“*”

如何在 Swift 中指出 for 循环的键是 NSString?