我正在浏览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也会导致子字符串也被删除?
答案 0 :(得分:3)
行为正确。
子字符串共享原始字符串的引用计数器。如果原始字符串被销毁,则引用仍然有效。
请从36:00开始观看WWDC 2017: What's new in Swift
实际上,甚至引用的文本也证实了这种行为,因为它表示在对字符串进行切片之后,整个字符串都保留在内存中。
答案 1 :(得分:1)
正如其他人所说,您的测试证实了您引用的问题:保留子字符串会保留对原始字符串的强烈引用,因此不会被释放。
想象一下,原始字符串是“战争与和平”的整个文本,而您得到了一个子字符串,其中包含“ and”的首次出现。只要保留该子字符串,战争与和平的整个文本就会保留在内存中。
您可以通过将子字符串转换为常规字符串来避免强引用:
let beginning = String(greeting?[..<index])