8

我读过几本书......和在线......关于不可变和可变字符串。他们声称“不可变字符串”无法更改。(但他们从不定义“改变”。)

哪些 NSString 可以在不使用 NSMutableString 的情况下进行更改?

该字符串包含“catfish”......我后来尝试将其更改为“cat”。(相同的字母,只是更短。)

它包含“猫”......我尝试将其更改为“鲶鱼”。(类似的开始......但只是变长了。)

我把“猫”改成“猫”。(相同的字母,但只是大小写发生了变化。)

我把“猫”变成了“狗”。(完全不同的字符串,但长度相同。)

我把“猫”改成了“山茱萸”。(完全不同的字符串,但更长。)

4

6 回答 6

20

答案是——没有。不可变意味着它不能更改为与原始字符串不同的任何内容。每个字符都保持不变,长度不能改变,等等。一旦它被定义,你就不能改变关于该字符串的任何内容。如果您想让它更长或更短或更改任何字符,您需要创建一个新字符串(或使用 NSMutableString 开头)。

于 2009-05-25T05:11:38.657 回答
11

如果我声明一个变量:

NSString * var;
// Here some code giving a new value to var

不可变的是 指向的对象var,而不是var它本身。

这意味着我无法更改 指向的对象的任何内容var,但我可以更改指向的对象。

您提到的任何操作都不允许在 上进行,但您可以使用另一个不同的字符串var进行分配:var

NSString * anotherVar;
// Here some code giving a new value to anotherVar

var = anotherVar; // This is allowed (with a memory leak if GC is disabled)

// The following is also allowed: -stringWithFormat: creates a new object
var = [var stringWithFormat:@"%@ with more chars", var];
于 2009-05-25T05:55:35.240 回答
3

NSString 不能被编辑,每次你为 NSString 对象分配一个字符串值时,它都会孤立旧的字符串对象并重新创建新的字符串对象。如果您正在处理大型字符串缓冲区,那将是一项昂贵的操作。如果您正在处理大型字符串缓冲区,请使用 NSMutableString 以获得最佳性能。这类似于 .net 中的 string vs stringBuilder。

于 2012-01-03T14:42:36.770 回答
2

你也需要定义“改变”:)

基本上,当您创建一个 NSString 时,您正在创建一个字符数组,并且您告诉编译器该数组的内容永远不会改变。“永不改变”部分是“不可变”部分;字符串包含的数据永远无法修改。

另一方面,NSMutableString 允许您实际更改它指向的数据(因此它是“可变的”)。注意 NSMutableString 存在的 'appendString' 方法;这实际上需要数据并将其拍到字符串的末尾。

例如,如果您有:

NSString *myString = @"猫"; myString = @"金鱼";

那会很好用。您永远不会真正更改 myString 包含的数据;您只是告诉它您希望它指向一个新的不可更改数据段。

唯一一次你真正遇到可变对象和不可变对象之间差异的问题是,如果你试图直接修改 myString (例如,将“s are cool”附加到它或其他东西)。

换句话说,任何一个类都允许您将任何字符串“更改”为任何其他字符串,但是您用来执行此操作的方法会非常不同。例如,要使用可变字符串将“cat”转换为“CAT”,您可以遍历每个字符并简单地将其设为大写(因为您可以修改可变字符串的内容)。另一方面,对于不可变字符串,您必须首先将原始字符串复制到其他地方,对其进行修改,然后将您的变量重定向到这个新的 NSString。

以下链接可能有用: http ://www.kirupa.com/forum/showthread.php?t= 307928 http://forums.macrumors.com/showthread.php?t=467099

我还建议做一些谷歌搜索;这是一个涉及到总体发展的问题,是一个比较重要的概念。它也在互联网上的其他地方被讨论到死。

于 2009-05-25T05:42:30.127 回答
2

不可变字符串(或者实际上是任何不可变对象)是在初始化后根本无法更改的字符串。

这是在(伪)伪代码中使用不可变字符串的优势:

// if using mutable strings
let a = "Hello World";
let b = a;
a.replace("Hello", "Goodbye");

现在持有什么?“你好世界”?“世界再见”?现在 b 持有什么?

如果字符串是可变的,那么它可能会保存“再见世界”。这可能是你想要的。可能不是。

有了不变性,很明显 b 仍然指向原始字符串,因为 replace 方法不能更改实际字符串,而是返回对新字符串的引用。

在此示例中,您可能看不到太多好处。但是如果 a 和 b 在代码的不同部分或不同的线程中被引用和使用,具有不可变引用会消除很多潜在的错误。

于 2009-05-25T06:29:30.427 回答
1

默认情况下,目标 C 语言中使用的 NSString 是不可变的。NSMutableString 用于声明和定义可变字符串。不可变字符串中的任何内容都无法更改。不是长度,不是字符,什么都没有。

于 2013-07-10T12:17:09.273 回答