字符串的子字符串重用原始字符串的存储?

时间:2018-10-28 18:01:36

标签: swift

我正在浏览swift docs的字符串和字符部分

这里提到:

  

子字符串不适合长期存储,因为它们会重复使用   原始字符串的存储,整个原始字符串必须为   只要它的任何子字符串都在使用,就保留在内存中。

我尝试在操场上对此进行测试,但是发生的事情似乎与上面提到的有所不同。我在操场上运行了以下代码:

var greeting : String? = "Hello, world!"
let index = greeting!.firstIndex(of: ",") ?? greeting!.endIndex
let beginning = greeting?[..<index]
print(beginning ?? "")
greeting = nil
print(beginning ?? "")

我希望打印的内容:

"Hello"
""

但是确切打印的是:

"Hello"
"Hello"

是否不必将原始字符串设置为nil也会导致子字符串也被删除?

2 个答案:

答案 0 :(得分:3)

行为正确。

子字符串共享原始字符串的引用计数器。如果原始字符串被销毁,则引用仍然有效。

请从36:00开始观看WWDC 2017: What's new in Swift

实际上,甚至引用的文本也证实了这种行为,因为它表示在对字符串进行切片之后,整个字符串都保留在内存中。

答案 1 :(得分:1)

正如其他人所说,您的测试证实了您引用的问题:保留子字符串会保留对原始字符串的强烈引用,因此不会被释放。

想象一下,原始字符串是“战争与和平”的整个文本,而您得到了一个子字符串,其中包含“ and”的首次出现。只要保留该子字符串,战争与和平的整个文本就会保留在内存中。

您可以通过将子字符串转换为常规字符串来避免强引用:

let beginning = String(greeting?[..<index])